2009-07-27 54 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