2009-07-27 5 views
4

Ich versuche, ein Programm in C zu schreiben, das erkennen kann, wenn einige Windows-Dienste (auch NT-Dienste genannt) gestartet oder gestoppt werden.Wie kann ich Statusänderungen von Windows-Diensten unter Windows XP überwachen?

Es scheint eine Funktion zu geben NotifyServiceStatusChange, aber das ist nur für Vista und Windows 7 verfügbar. Ich versuche, dies auf Win XP zu tun, also, was ist der beste Weg? Gibt es andere als kontinuierliche Abfragen?

edit:

Ist jemand in der Lage Antwort in C zu geben? Ich bin auch mit C++ in Ordnung, aber ich möchte mich vom Scripting fernhalten.

+0

Da dies nicht eine qualifizierte Antwort, die ich hinzugefügt habe es als Kommentar: die nächstgelegene Sie erhalten können, ist 'RegNotifyChangeKeyValue' das' HKLM \ SYSTEM \ CurrentControlSet \ services' Schlüssel für maschinen lokale Dienste beobachten –

Antwort

3

Sieht so aus, als ob Sie in XP am nähesten kommen können: QueryServiceStatusEx (einzelner Dienst) oder EnumServicesStatusEx (mehrere Dienste).

Um das wiederholte Aufrufen dieser beiden zu vermeiden, empfehlen einige ein WMI-Setup, das die -Eigenschaft state abfragt. Weitere Informationen finden Sie unter this thread.

Im Folgenden ist ein (unverwässert) WMI-Skript des Warndienstes Status zu überwachen:

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

Die obigen und weitere Beispiele kann auf this TechNet page finden.

0

Sie müssen dies durch Abfragen tun. Platzieren Sie den Code in einem separaten Thread und senden Sie ihn so lange wie möglich in den Ruhezustand. Sagen Sie jede Sekunde, vielleicht sogar 5 Sekunden, um die Systemleistung zu minimieren.

Als 'c' Beispiel für einen einzelnen Dienst:

// verschiedene Griffe und Streicher plus ... 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; 
     } 

Das Ergebnis werden Sie in der ssStatus.dwCurrentState sein wollen.

+0

Es gibt einige andere Optionen außer Polling, z. B. WMI –

+0

@Thomasek WMI ruft weiterhin die Dienste ab. Das ursprüngliche Poster bat um eine XP-Lösung und wies darauf hin, dass NotifyServiceStatusChange in XP * nicht * verfügbar ist. Umfragen sind alles andere als ideal. Aber wenn es einen * XP * Weg gibt, den Service-Status ohne ihn zu lesen (auf irgendeiner Ebene), wäre ich sehr interessiert daran zu wissen. –

Verwandte Themen