Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Wenn ein Dienststeuerungsprogramm anfordert, dass ein neuer Dienst ausgeführt wird, startet der Service Control Manager (SCM) den Dienst und sendet eine Startanforderung an den Kontrollteiler. Der Steuerelementverteiler erstellt einen neuen Thread zum Ausführen der ServiceMain--Funktion für den Dienst. Ein Beispiel finden Sie unter Schreiben einer ServiceMain-Funktion.
Die ServiceMain--Funktion sollte die folgenden Aufgaben ausführen:
Initialisieren Sie alle globalen Variablen.
Rufen Sie die RegisterServiceCtrlHandler- Funktion sofort auf, um eine Handler--Funktion zu registrieren, um Steueranforderungen für den Dienst zu verarbeiten. Der Rückgabewert von RegisterServiceCtrlHandler ist ein Dienststatushandle, das in Aufrufen verwendet wird, um den SCM über den Dienststatus zu benachrichtigen.
Initialisierung durchführen. Wenn die Ausführungszeit des Initialisierungscodes voraussichtlich sehr kurz ist (weniger als eine Sekunde), kann die Initialisierung direkt in ServiceMainausgeführt werden.
Wenn die Initialisierungszeit voraussichtlich länger als eine Sekunde ist, sollte der Dienst eine der folgenden Initialisierungstechniken verwenden:
Rufen Sie die SetServiceStatus--Funktion auf, um SERVICE_RUNNING zu melden, aber akzeptieren Sie keine Steuerelemente, bis die Initialisierung abgeschlossen ist. Der Dienst führt dies aus, indem SetServiceStatus- mit dwCurrentState- auf SERVICE_RUNNING und dwControlsAccepted- in der SERVICE_STATUS-Struktur auf 0 festgelegt ist. Dadurch wird sichergestellt, dass der SCM keine Kontrollanforderungen an den Dienst sendet, bevor er bereit ist und das SCM zur Verwaltung anderer Dienste freigibt. Dieser Ansatz für die Initialisierung wird für die Leistung empfohlen, insbesondere für Autostartdienste.
Melden Sie SERVICE_START_PENDING, akzeptieren Sie keine Steuerelemente, und geben Sie einen Wartehinweis an. Wenn der Initialisierungscode Ihres Diensts Aufgaben ausführt, die voraussichtlich länger dauern als der anfängliche Wartehinweiswert, muss Ihr Code die SetServiceStatus- funktion regelmäßig aufrufen (möglicherweise mit einem überarbeiteten Wartehinweis), um anzugeben, dass der Fortschritt erfolgt. Rufen Sie SetServiceStatus- nur auf, wenn die Initialisierung Fortschritte erzielt. Andernfalls kann der SCM warten, bis Ihr Dienst in den SERVICE_RUNNING Zustand wechselt, vorausgesetzt, dass Ihr Dienst Fortschritte macht und andere Dienste am Start hindert. Rufen Sie nicht SetServiceStatus- von einem separaten Thread auf, es sei denn, Sie sind sicher, dass der Thread, der die Initialisierung ausführt, wirklich Fortschritte erzielt.
Ein Dienst, der diesen Ansatz verwendet, kann auch einen Check-Point-Wert angeben und den Wert während einer langen Initialisierung regelmäßig erhöhen. Das Programm, das den Dienst gestartet hat, kann QueryServiceStatus- oder QueryServiceStatusEx aufrufen, um den neuesten Check-Point-Wert aus dem SCM abzurufen und den Wert zu verwenden, um den inkrementellen Fortschritt an den Benutzer zu melden.
Rufen Sie nach Abschluss der Initialisierung SetServiceStatus- auf, um den Dienststatus auf SERVICE_RUNNING festzulegen, und geben Sie die Steuerelemente an, die der Dienst akzeptiert. Eine Liste der Steuerelemente finden Sie in der SERVICE_STATUS Struktur.
Führen Sie die Dienstaufgaben aus, oder geben Sie, wenn keine ausstehenden Aufgaben vorhanden sind, die Steuerung an den Aufrufer zurück. Jede Änderung des Dienststatus garantiert einen Aufruf von SetServiceStatus-, um neue Statusinformationen zu melden.
Wenn während der Initialisierung oder Ausführung des Diensts ein Fehler auftritt, sollte der Dienst SetServiceStatus- aufrufen, um den Dienststatus auf SERVICE_STOP_PENDING festzulegen, wenn die Bereinigung lang ist. Rufen Sie nach Abschluss der Bereinigung SetServiceStatus- auf, um den Dienststatus vom letzten zu beendenden Thread auf SERVICE_STOPPED festzulegen. Stellen Sie sicher, dass Sie die dwServiceSpecificExitCode- und dwWin32ExitCode Member der SERVICE_STATUS Struktur festlegen, um den Fehler zu identifizieren.
Verwandte Themen