You can use the __InstanceDeletionEvent
WMI intrinsic event to monitor the Win32_Process
class and the filter by the ProcessId
property, this event run in async mode in your code.
Check this sample code (Written in delphi XE2, but must work in delphi 6 without problems)
Note : You must import the Microsoft WMI Scripting V1.2 Library before to use it.
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, WbemScripting_TLB;
type
TWmiAsyncEvent = class
private
FWQL : string;
FSink : TSWbemSink;
FLocator : ISWbemLocator;
FServices : ISWbemServices;
procedure EventReceived(ASender: TObject; const objWbemObject: ISWbemObject; const objWbemAsyncContext: ISWbemNamedValueSet);
public
procedure Start;
constructor Create(Pid : DWORD);
Destructor Destroy;override;
end;
TFrmDemo = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
AsyncEvent : TWmiAsyncEvent;
public
{ Public declarations }
end;
var
FrmDemo: TFrmDemo;
implementation
{$R *.dfm}
uses
ActiveX;
{ TWmiAsyncEvent }
constructor TWmiAsyncEvent.Create(Pid: DWORD);
begin
inherited Create;
CoInitializeEx(nil, COINIT_MULTITHREADED);
FLocator := CoSWbemLocator.Create;
FServices := FLocator.ConnectServer('.', 'root\CIMV2', '', '', '', '', wbemConnectFlagUseMaxWait, nil);
FSink := TSWbemSink.Create(nil);
FSink.OnObjectReady := EventReceived;
//construct the WQL sentence with the pid to monitor
FWQL:=Format('Select * From __InstanceDeletionEvent Within 1 Where TargetInstance ISA "Win32_Process" And TargetInstance.ProcessId=%d',[Pid]);
end;
destructor TWmiAsyncEvent.Destroy;
begin
if FSink<>nil then
FSink.Cancel;
FLocator :=nil;
FServices :=nil;
FSink :=nil;
CoUninitialize;
inherited;
end;
procedure TWmiAsyncEvent.EventReceived(ASender: TObject;
const objWbemObject: ISWbemObject;
const objWbemAsyncContext: ISWbemNamedValueSet);
var
PropVal: OLEVariant;
begin
PropVal := objWbemObject;
//do something when the event is received.
ShowMessage(Format('The Application %s Pid %d was finished',[String(PropVal.TargetInstance.Name), Integer(PropVal.TargetInstance.ProcessId)]));
end;
procedure TWmiAsyncEvent.Start;
begin
FServices.ExecNotificationQueryAsync(FSink.DefaultInterface,FWQL,'WQL', 0, nil, nil);
end;
procedure TFrmDemo.FormCreate(Sender: TObject);
begin
//here you must pass the pid of the process
AsyncEvent:=TWmiAsyncEvent.Create(1852);
AsyncEvent.Start;
end;
procedure TFrmDemo.FormDestroy(Sender: TObject);
begin
AsyncEvent.Free;
end;
end.
For more info you can check this article Delphi and WMI Events