Kawaii-Hachii
Kawaii-Hachii

Reputation: 1061

Windows Last Boot Date & Time using Delphi

How to get the date & time of the last boot / reboot / restart on Windows 2008/2003 machine?

I know from command prompt we can use "net statistics", but how to do it via Delphi?

Thanks.

Upvotes: 2

Views: 4758

Answers (4)

RRUZ
RRUZ

Reputation: 136391

You can use the LastBootUpTime property of the Win32_OperatingSystem WMI Class, which return the Date and time the operating system was last restarted (Note : the returned value of this property is in UTC format).

Check this sample app

{$APPTYPE CONSOLE}

uses
  SysUtils,
  ActiveX,
  Variants,
  ComObj;


//Universal Time (UTC) format of YYYYMMDDHHMMSS.MMMMMM(+-)OOO.
//20091231000000.000000+000
function UtcToDateTime(const V : OleVariant): TDateTime;
var
  Dt : OleVariant;
begin
  Result:=0;
  if VarIsNull(V) then exit;
  Dt:=CreateOleObject('WbemScripting.SWbemDateTime');
  Dt.Value := V;
  Result:=Dt.GetVarDate;
end;

procedure  GetWin32_OperatingSystemInfo;
const
  WbemUser            ='';
  WbemPassword        ='';
  WbemComputer        ='localhost';
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService   := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
  FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_OperatingSystem','WQL',wbemFlagForwardOnly);
  oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  if oEnum.Next(1, FWbemObject, iValue) = 0 then
  begin
    Writeln(Format('Last BootUp Time    %s',[FWbemObject.LastBootUpTime]));// In utc format
    Writeln(Format('Last BootUp Time    %s',[formatDateTime('dd-mm-yyyy hh:nn:ss',UtcToDateTime(FWbemObject.LastBootUpTime))]));// Datetime
  end;
end;


begin
 try
    CoInitialize(nil);
    try
      GetWin32_OperatingSystemInfo;
    finally
      CoUninitialize;
    end;
 except
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;
end.

Upvotes: 7

JosephStyons
JosephStyons

Reputation: 58685

Here is a complete command line application that does what you are talking about. I've modified this to avoid the GetTickCount overflow issues without relying on external function calls.

Example output:

Windows was last rebooted at: 06/29/2011 9:22:47 AM

Have fun!

program lastboottime;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Windows;

function UptimeInDays: double;
const
  c_SecondsInADay = 86400;
var
  cnt, freq: Int64;
begin
  QueryPerformanceCounter(cnt);
  QueryPerformanceFrequency(freq);
  Result := (cnt / freq) / c_SecondsInADay;
end;

function LastBootTime: TDateTime;
begin
  Result := Now() - UptimeInDays;
end;

begin
  try
    WriteLn('Windows was last rebooted at: ' + DateTimeToStr(LastBootTime));
    ReadLn;
  except on E: Exception do
    Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Upvotes: 3

Cosmin Prund
Cosmin Prund

Reputation: 25678

Here's a bit of code that uses GetTickCount64 if available and falls back to GetTickCount if unavailable to compute the date and time of system startup. This is not a perfect solution because GetTickCount64 is only supported on Vista+ : if you're on older Windows, the counter goes back to 0 every 49 days.

program Project29;

{$APPTYPE CONSOLE}

uses
  SysUtils, Windows;

type
  TGetTickCount64 = function : Int64; stdcall;

var
  H_K32: HMODULE;
  Tick64Proc: TGetTickCount64;

function BootTime: TDateTime;
var UpTime: Int64;
    Seconds, Minutes, Hours: Int64;
begin
  if H_K32 = 0 then
  begin
    H_K32 := LoadLibrary(kernel32);
    if H_K32 = 0 then
      RaiseLastOSError
    else
      begin
        Tick64Proc := GetProcAddress(H_K32, 'GetTickCount64');
     end;
  end;

  if Assigned(Tick64Proc) then
    UpTime := Tick64Proc
  else
    UpTime := GetTickCount;

  Result := Now - EncodeTime(0, 0, 0, 1) * UpTime;
end;

begin
  WriteLn(DateTimeToStr(BootTime));
  ReadLn;
end.

Upvotes: 2

ain
ain

Reputation: 22749

The GetTickCount function (see MSDN) returns the number of milliseconds that have elapsed since the system was started, so divide it with 1000 to get seconds, with 60 000 to get minutes etc.

The topic I linked also contains this bit:

To obtain the time elapsed since the computer was started, retrieve the System Up Time counter in the performance data in the registry key HKEY_PERFORMANCE_DATA. The value returned is an 8-byte value. For more information, see Performance Counters.

Upvotes: 1

Related Questions