我需要观察 Windows 计算机上某些进程何时启动或停止。我目前正在使用 WMI 系统并每 5 秒查询一次,但这会导致每 5 秒出现一次 CPU 峰值,因为 WMI 是 WMI。有更好的方法吗?我可以只列出正在运行的进程,并通过 System.Diagnostics 命名空间将 Exited 事件附加到它们,但没有用于创建的事件处理程序。
如果您只想查找进程的 PID/名称,您可能希望使用 WQL 查询来获取 Win32_ProcessTrace 事件,例如“SELECT * FROM Win32_ProcessTrace WHERE TargetInstance.ProcessName = 'name'”如果适用*.
使用“SELECT * FROM __InstanceModificationEvent Within 10 WHERE TargetInstance ISA 'Win32Process' AND TargetInstance.Name = 'name'”的缺陷在于它在后端的工作方式。如果您检查 %windir%\system32\wbem\logs 目录中的 wbemess.log,您将注意到以下日志(使用 __InstanceDeletionEvent):
(Wed Jul 22 13:58:31 2009.73889577) : Registering notification sink with query select * from __InstanceDeletionEvent within 10 where TargetInstance ISA 'Win32_Process' in namespace //./root/CIMV2.
(Wed Jul 22 13:58:31 2009.73889577) : Activating filter 047209E0 with query select * from __InstanceDeletionEvent within 10 where TargetInstance ISA 'Win32_Process' in namespace //./root/CIMV2.
(Wed Jul 22 13:58:31 2009.73889577) : Activating filter 0225E560 with query select * from __ClassOperationEvent where TargetClass isa "Win32_Process" in namespace //./root/CIMV2.
(Wed Jul 22 13:58:31 2009.73889577) : Activating filter 'select * from __ClassOperationEvent where TargetClass isa "Win32_Process"' with provider $Core
(Wed Jul 22 13:58:31 2009.73889587) : Activating filter 'select * from __InstanceDeletionEvent within 10 where TargetInstance ISA 'Win32_Process'' with provider $Core
(Wed Jul 22 13:58:31 2009.73889587) : Instituting polling query select * from Win32_Process to satisfy event query select * from __InstanceDeletionEvent within 10 where TargetInstance ISA 'Win32_Process'
(Wed Jul 22 13:58:31 2009.73889587) : Executing polling query 'select * from Win32_Process' in namespace '//./root/CIMV2'
(Wed Jul 22 13:58:31 2009.73889697) : Polling query 'select * from Win32_Process' done
(Wed Jul 22 13:58:41 2009.73899702) : Executing polling query 'select * from Win32_Process' in namespace '//./root/CIMV2'
(Wed Jul 22 13:58:41 2009.73899792) : Polling query 'select * from Win32_Process' done
正如您所看到的,远程计算机上的实际事件实现是按照WITHIN 子句中的值指定的时间间隔对Win32_Process 执行查询。因此,在该轮询中启动和停止的任何进程都不会触发事件。
您可以将WITHIN子句设置为一个较小的值,以尽量减少这种影响,但更好的解决方案是使用像Win32_ProcessTrace这样的真实事件,它应该always fire.
*请注意,MSDN 表明 Win32_ProcessTrace 至少需要客户端计算机上的 Windows XP 和服务器计算机上的 Windows 2003 才能工作。如果您使用的是较旧的操作系统,则可能会因使用 __InstanceModificationEvent 查询而陷入困境。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)