2009-07-27 55 views
4

我想在C中编写一个程序,它可以检测到某些Windows服务(又名.NT服务)何时启动或停止。如何监视windows xp下windows服务的状态变化?

似乎有一个功能NotifyServiceStatusChange,但这只在Vista和Windows 7上可用。我试图在Win XP上这样做,所以最好的方法是什么?除了连续轮询之外还有其他什么吗?

编辑:

是否有人能够在C中给出答案?我也可以用C++,但我想远离脚本。

+0

由于这不是一个合格的答案,所以我将它添加为注释:最近可以得到的是`RegNotifyChangeKeyValue`,用于查看机器本地服务的`HKLM \ SYSTEM \ CurrentControlSet \ services`键 – 2018-01-07 18:37:30

回答

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." 

上面,和另外的实施例,可以在this TechNet page找到。

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结果。

+0

还有一些其他选项除了轮询,如WMI – 2011-03-08 15:08:42