tags:

views:

388

answers:

4

What is the function to get date and time an application was executed? I'm using Delphi.

+3  A: 

I'm not sure if there's a function or API call for this. But you can fake it pretty easily. Create a unit that looks like this:

unit AppStartTime;

interface

function GetAppStartTime: TDateTime;

implementation
uses
  SysUtils;

var
  fStartTime: TDateTime;

function GetAppStartTime: TDateTime;
begin
  result := fStartTime;
end;

initialization
  fStartTime := Now;

end.

Add it to your DPR's uses list, at the top, either first or immediately after anything that "must be first on the list", such as a custom memory manager.

Mason Wheeler
If you want to be really accurate, and your application has a long start up, then put this unit as the first in your uses clause.
Jim McKeeth
If you want to be *really* accurate you need to use `GetProcessTimes()`, as even the code in the initialization of the very first unit will be executed only after all modules have been loaded and all module entry points have been resolved, which can take quite a lot of time with low I/O bandwidth and nothing preloaded or cached.
mghie
+1  A: 

You can have your app log the startup time to a text file or database either in the DPR file or in your main form's OnCreate() event. You can use Delphi's Now() function to get the current date and time, and format it as a string using FormatDateTime() or DateTimeToStr(), depending on what exactly you're looking to do.

The code below saves the startup date and time during the main form's constructor to a text file in the same folder as the application itself called StartDateTime.txt:

procedure TForm1.FormCreate(Sender: TObject);
var
  SL: TStringList;
begin
  SL := TStringList.Create;
  try
    SL.Add(FormatDateTime('mm/dd/yyyy hh:nn:ss', Now());
    SL.SaveToFile(ExtractFilePath(ParamStr(0)) + 'StartDateTime.txt');
  finally
    SL.Free;
  end;
end;
Ken White
Does your answer contradict Bruces?
Peter Turner
Peter. No. His answer is close to the second part of my answer, except Ken posted his first and included source code. If that's the way you choose to go, you should select Ken's answer as the correct one.
Bruce McGee
I'd still prefer the first sentence of the answer to be removed - it is clearly wrong.
mghie
@mghie: Done. I missed GetProcessTimes(). Mea culpa.
Ken White
@Bruce: Actually, yours is the better answer. Mine is only better on versions of Windows prior to GetProcessTimes() being available. :-)
Ken White
Thanks for the clarification. It's true MSDN says GetProcessTimes Minimum supported client is Windows 2000 Professional. So in certain unfortunate circumstances this may be the way to go.
Peter Turner
@Ken, you're going to make me blush.
Bruce McGee
@Bruce: Gee, I guess I shouldn't tell you I voted your answer up then. <g>
Ken White
+13  A: 

You can use the Windows API call to GetProcessTimes (declared in Windows.pas) to get details for any process.

If it's your application, I would probably get the start time myself and log it somewhere to keep a history.

Bruce McGee
+1 for GetProcessTimes
RRUZ
And the simplest way to use it is DSiGetProcessTimes from DSiWin32, http://gp.17slon.com/gp/dsiwin32.htm.
gabr
@gabr. nice link. Thanks.
Bruce McGee
+1  A: 

Use NtQuerySystemInformation with the SystemProcessInformation informationclass, this returns an array of SYSTEM_PROCESSES structures (records) of which the CreateTime contains the exact time when the applications was started:

  _SYSTEM_PROCESSES = record // Information Class 5
    NextEntryDelta: ULONG;
    ThreadCount: ULONG;
    Reserved1: array[0..5] of ULONG;
    CreateTime: LARGE_INTEGER;
    UserTime: LARGE_INTEGER;
    KernelTime: LARGE_INTEGER;
    ProcessName: UNICODE_STRING;
    BasePriority: KPRIORITY;
    ProcessId: ULONG;
    InheritedFromProcessId: ULONG;
    HandleCount: ULONG;
    // next two were Reserved2: array [0..1] of ULONG; thanks to Nico Bendlin
    SessionId: ULONG;
    Reserved2: ULONG;
    VmCounters: VM_COUNTERS;
    PrivatePageCount: ULONG;
    IoCounters: IO_COUNTERSEX; // Windows 2000 only
    Threads: array[0..0] of SYSTEM_THREADS;
  end;
  SYSTEM_PROCESSES = _SYSTEM_PROCESSES;
  PSYSTEM_PROCESSES = ^SYSTEM_PROCESSES;
  TSystemProcesses = SYSTEM_PROCESSES;
  PSystemProcesses = PSYSTEM_PROCESSES;

We have already translated all of this in the Jedi Apilib (JwaNative)

Remko
That's not the structure documented on MSDN, so I'd hesitate to trust its accuracy.
Rob Kennedy
Well Microsoft has kept this function undocumented and now they are partly documented. The structure has been reversed a very long time ago though so I think it's very well safe to use.
Remko