views:

99

answers:

5

How to catch the start and completion of applications (processes) in Win. How to measure the time of each application?

+2  A: 

There are a couple or so Windows API calls with 'hook' in the name that allow you to capture systemwide events. You'll have to build those into a DLL, and then make calls to the 'hooking' DLL from a separate application.

That, VERY briefly, is it. Hope that gets you started!

Carl Smotricz
+2  A: 

You can use the GetProcessTimes function to get timing information for a particular process.

BOOL WINAPI GetProcessTimes(
  __in   HANDLE hProcess,
  __out  LPFILETIME lpCreationTime,
  __out  LPFILETIME lpExitTime,
  __out  LPFILETIME lpKernelTime,
  __out  LPFILETIME lpUserTime
);

See this example

program GetProcessTime;

{$APPTYPE CONSOLE}

uses
  DateUtils,
  Windows,
  tlhelp32,
  SysUtils;


Procedure  GetAllProcessTime;
var
  HandleSnapShot   : THandle;
  EntryParentProc  : TProcessEntry32;
  DummyCreateFileTime : Windows.FILETIME;
  DummyExitFileTime   : Windows.FILETIME;
  DummyKernelFileTime : Windows.FILETIME;
  DummyUserFileTime   : Windows.FILETIME;
  aFileName           : String;
  h                   : THandle;
  ActualTime          : TDateTime;
  Dif                 : TDateTime;
  CreationTime        : TDateTime;


function FileTime2DateTime(FileTime: TFileTime): TDateTime;    //Convert then FileTime to TDatetime format
var
  LocalTime: TFileTime;
  DOSTime  : Integer;
begin
  FileTimeToLocalFileTime(FileTime, LocalTime);
  FileTimeToDosDateTime(LocalTime, LongRec(DOSTime).Hi, LongRec(DOSTime).Lo);
  Result := FileDateToDateTime(DOSTime);
end;

begin
  HandleSnapShot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);  //get the list of process
  if HandleSnapShot <> INVALID_HANDLE_VALUE then
  begin
    EntryParentProc.dwSize := SizeOf(EntryParentProc);
    if Process32First(HandleSnapShot, EntryParentProc) then   //Get the first process in the list
    begin
      Writeln( Format('%-30s %-20s %-16s',['FileName','Start','Running Time'])  );
      ActualTime:=Now;
      repeat
          h:=OpenProcess(PROCESS_QUERY_INFORMATION,false,EntryParentProc.th32ProcessID);  //open a particular process
          if GetProcessTimes(h, DummyCreateFileTime, DummyExitFileTime, DummyKernelFileTime, DummyUserFileTime) then  //get the timing  info
          begin
            aFileName:=ExtractFileName(EntryParentProc.szExeFile);
            CreationTime:=FileTime2DateTime(DummyCreateFileTime); //get the initial time of the process
            Dif :=  ActualTime-CreationTime; //calculate the elapsed time
            Writeln( Format('%-30s %-20s %-16s',[aFileName,FormatDateTime('DD-MM-YYYY HH:NN:SS',CreationTime),FormatDateTime('HH:NN:SS',Dif)])  );
          end;
          CloseHandle(h);
      until not Process32Next(HandleSnapShot, EntryParentProc);
    end;
    CloseHandle(HandleSnapShot);
  end;

end;



begin
  try
    GetAllProcessTime();
    Readln;
  except
    on E: Exception do
    begin
     Writeln(E.ClassName, ': ', E.Message);
     Readln;
    end;
  end;
end.
RRUZ
+1  A: 

the WH_CBT hook is most likely the one you are after. It allows you to be notified by the OS whenever a window is created or destroyed. You will want to use this hook to grab the handle and from the handle get the process id using GetWindowThreadProcessId. You can then pass this handle to the function GetProcessTimes (suggested by RRUZ) to get the times. An example (although dated, the concepts are still the same) is available in the GpSysHook source.

skamradt
+1  A: 

Windows Performance Analyzer has features specifically for timing applications from the moment they start, even if they're in the boot or log-in sequence.

Adrian McCarthy
+1  A: 

Windows Management Instrumentation offers event subscription. The nice thing with WMI is that it works remote too, using DCOM and SOAP.

WMI offers the capability to notify a subscriber for any event it is interested in.

WMI uses the WMI Query Language (WQL) to submit WQL event queries and defines the type of events to be returned. The eventing mechanism, with all related callbacks, is part of the WMI COM/DCOM and automation interfaces.

A free WMI client implementation for Delphi is avalable online (not sure if it supports event callbacks):

Magenta Systems WMI and SMART Component

mjustin