如何在Windows XP下监控Windows服务的状态变化?

我正在尝试用C编写一个程序,它可以检测何时启动或停止某些Windows服务(即NT服务)。

似乎有一个函数NotifyServiceStatusChange ,但这只适用于Vista和Windows 7.我试图在Win XP上执行此操作,那么最好的方法是什么? 除连续投票外还有其他吗?

编辑:

有人能用C答案吗? 我也熟悉C ++,但我想远离脚本。

看起来你在XP中最接近的是QueryServiceStatusEx (单一服务)或EnumServicesStatusEx (多种服务)。

为避免反复调用其中任何一个,有人建议使用WMI设置,查询Win32_Servicestate属性。 有关更多详细信息,请参阅此主题的底部。

以下是监视警报器服务状态的(基本)WMI脚本:

 strComputer = "." Set objSWbemServices = GetObject("winmgmts:" &_ "{impersonationLevel=impersonate}!" &_ "\\" & strComputer & "\root\cimv2") Set objEventSource = objSWbemServices.ExecNotificationQuery( _ "SELECT * FROM __InstanceModificationEvent " &_ "WITHIN 10 " &_ "WHERE TargetInstance " &_ "ISA 'Win32_Service' " &_ "AND TargetInstance.Name = 'alerter'") Set objEventObject = objEventSource.NextEvent() Wscript.Echo "The status of the alerter service just changed." 

可以在此TechNet页面上找到上述和其他示例。

您需要通过轮询来完成。 将代码放在一个单独的线程中,并在合理的时间内将其发送到hibernate状态。 说每秒,甚至5秒钟,以最小化系统性能。

作为单个服务的“c”示例:

//各种句柄和字符串加上…… SERVICE_STATUS ssStatus; …

  schSCManager = OpenSCManager( ServiceComputerNameStr, NULL, SC_MANAGER_ALL_ACCESS ); if ( schSCManager == NULL ) { // ... error stuff goto cleanup; } scphService = OpenService( schSCManager, ServiceNameStr, // SERVICE_QUERY_STATUS ); SERVICE_ALL_ACCESS ); if ( scphService == NULL ) { // ... error stuff goto cleanup; } if ( !QueryServiceStatus(scphService, ssStatus) ) { // ... error stuff goto cleanup; } 

您想要的结果将在ssStatus.dwCurrentState中。