如何在Windows XP下监控Windows服务状态的更改?

4
我正在尝试用C语言编写一个程序,可以检测Windows服务(也称为NT服务)何时启动或停止。
似乎有一个函数NotifyServiceStatusChange,但这仅适用于Vista和Windows 7。我正在尝试在Win XP上做到这一点,那么最好的方法是什么?除了持续轮询之外还有其他方法吗?
编辑:
有人能够用C语言回答吗?我也可以接受C ++,但我想避免脚本。

由于这不是一个合格的答案,我将其作为评论添加:最接近的方法是使用RegNotifyChangeKeyValue监视机器本地服务的HKLM\SYSTEM\CurrentControlSet\services键。 - klaus triendl
2个回答

3

看起来在XP中最接近的方法是QueryServiceStatusEx(单个服务)或EnumServicesStatusEx(多个服务)。

为了避免反复调用它们,一些人建议使用WMI设置,查询Win32_Servicestate属性。有关更多详细信息,请参见this thread底部。

以下是(基本)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页面上找到。

0

你需要通过轮询来完成。将代码放在单独的线程中,并让它睡眠尽可能长的时间。例如每秒钟一次,甚至每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中。


除了轮询,还有一些其他选项,例如 WMI。 - Tomas Walek
@Thomasek WMI仍在轮询服务。原帖作者要求XP解决方案,并且正如他所指出的,NotifyServiceStatusChange在XP中是不可用的。轮询远非理想。但是,如果有一种 XP *的读取服务状态的方法(在某个级别上)而不需要它,我会非常感兴趣了解。 - David L Morris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接