Rob*_*ler 5 delphi winapi skype process
我有一个与Skype API一起使用的Delphi 6应用程序.我想知道Skype客户端何时关闭,即使我的软件没有启动它(所以我没有它的进程句柄).通过这种方式,我可以知道用户是否关闭Skype客户端我可以非常轻松地获取Skype客户端的进程ID,因此是否有Windows API调用或其他接受进程ID的技术,我可以在进程中获取通知(Skype客户端)已经终止?
如果没有,是否有一个WinApi调用可用于轮询Windows以查看进程ID是否仍然有效,或者Windows是否重用进程ID,因此我有可能最终获得属于最近启动的进程的进程ID那不是Skype客户端,这会使我的投票工作无效吗?
arx*_*arx 12
调用OpenProcess来获取进程句柄.该SYNCHRONIZE
访问权可能就足够了.然后等待手柄.就像是:
HANDLE hProcess = OpenProcess(SYNCHRONIZE, FALSE, pid);
WaitForSingleObject(hProcess, INFINITE);
CloseHandle(hProcess);
Run Code Online (Sandbox Code Playgroud)
您可以使用__InstanceDeletionEvent
WMI内部事件来Win32_Process
按ProcessId
属性监视类和过滤器,此事件在代码中以异步模式运行.
检查此示例代码(以delphi XE2编写,但必须在delphi 6中正常工作而不会出现问题)
注意:您必须先导入Microsoft WMI Scripting V1.2 Library才能使用它.
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.
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请查看此文章 Delphi and WMI Events
归档时间: |
|
查看次数: |
867 次 |
最近记录: |