Dienststeuerungshandler-Funktion

Jeder Dienst verfügt über einen Steuerelementhandler, die Handler-Funktion, die vom Steuerelement-Verteiler aufgerufen wird, wenn der Dienstprozess eine Steuerungsanforderung von einem Dienststeuerungsprogramm empfängt. Daher wird diese Funktion im Kontext des Steuerelement-Verteilers ausgeführt. Ein Beispiel finden Sie unter Schreiben einer Steuerelementhandlerfunktion.

Ein Dienst ruft die RegisterServiceCtrlHandler- oder RegisterServiceCtrlHandlerEx-Funktion auf, um seine Dienststeuerungshandlerfunktion zu registrieren.

Wenn der Dienststeuerungshandler aufgerufen wird, muss der Dienst die Funktion SetServiceStatus aufrufen, um den Status nur dann an den SCM zu melden, wenn die Behandlung des Steuerungscodes bewirkt, dass sich der Dienststatus ändert. Wenn die Behandlung des Steuerungscodes nicht dazu führt, dass sich der Dienststatus ändert, ist es nicht erforderlich, SetServiceStatus auf aufruft.

Ein Dienststeuerungsprogramm kann Steuerungsanforderungen mithilfe der ControlService-Funktion senden. Alle Dienste müssen den SERVICE _ CONTROL _ INTERROGATE-Steuerungscode akzeptieren und verarbeiten. Sie können die Akzeptanz der anderen Steuerelementcodes aktivieren oder deaktivieren, indem Sie SetServiceStatus aufrufen. Um den SERVICE _ CONTROL _ DEVICEEVENT-Steuerungscode zu erhalten, müssen Sie die RegisterDeviceNotification-Funktion aufrufen. Dienste können auch zusätzliche benutzerdefinierte Steuerungscodes verarbeiten.

Wenn ein Dienst den SERVICE _ CONTROL STOP-Steuerungscode _ akzeptiert, muss er nach dem Empfang beendet werden und entweder in den Status SERVICE STOP _ _ PENDING oder SERVICE _ STOPPED gehen. Nachdem der SCM diesen Steuerungscode gesendet hat, sendet er keine anderen Steuerungscodes.

Windows XP: Wenn der Dienst NO _ ERROR zurückgibt und weiterhin ausgeführt wird, erhält er weiterhin Steuerungscodes. Dieses Verhalten hat sich seit Windows Server 2003 und Windows XP mit Service Pack 2 (SP2) geändert.

Der Steuerelementhandler muss innerhalb von 30 Sekunden zurückgeben, oder der SCM gibt einen Fehler zurück. Wenn ein Dienst eine lange Verarbeitung durchführen muss, wenn der Dienst den Steuerelementhandler ausgeführt, sollte er einen sekundären Thread erstellen, um die langwierige Verarbeitung durchzuführen, und dann vom Steuerelementhandler zurückgeben. Dadurch wird verhindert, dass der Dienst den Steuerelement-Verteiler binden kann. Wenn Sie z. B. die Stoppanforderung für einen Dienst behandeln, der lange dauert, erstellen Sie einen weiteren Thread, um den Stoppprozess zu verarbeiten. Der Steuerelementhandler sollte einfach SetServiceStatus mit der SERVICE STOP _ _ PENDING-Meldung aufrufen und zurückgeben.

Wenn der Benutzer das System heruntergefahren hat, erhalten alle Steuerelementhandler, die SetServiceStatus mit dem SERVICE ACCEPT _ _ PRESHUTDOWN-Steuerelementcode aufgerufen haben, den STEUERUNGscode SERVICE CONTROL _ _ PRESHUTDOWN. Der Dienststeuerungs-Manager wartet, bis der Dienst beendet wird oder der angegebene Preshutdown-Time out-Wert abläuft (dieser Wert kann mit der ChangeServiceConfig2-Funktion festgelegt werden). Dieser Steuerungscode sollte nur unter besonderen Umständen verwendet werden, da ein Dienst, der diese Benachrichtigung verarbeitet, das Herunterfahren des Systems blockiert, bis der Dienst beendet wird oder das Time out-Intervall für das vorab heruntergefahrene System abläuft.

Nachdem die Vorab-Benachrichtigungen abgeschlossen wurden, erhalten alle Steuerelementhandler, die SetServiceStatus mit dem SERVICE ACCEPT _ SHUTDOWN-Steuerungscode _ aufgerufen haben, den Steuerungscode SERVICE CONTROL _ _ SHUTDOWN. Sie werden in der Reihenfolge benachrichtigt, in der sie in der Datenbank der installierten Dienste angezeigt werden. Standardmäßig hat ein Dienst ca. 20 Sekunden Zeit, um Bereinigungsaufgaben auszuführen, bevor das System heruntergefahren wird. Nach Ablauf dieser Zeit wird das Herunterfahren des Systems unabhängig davon fortgesetzt, ob das Herunterfahren des Diensts abgeschlossen ist. Beachten Sie, dass der Dienst weiterhin ausgeführt wird, wenn sich das System im Herunterfahrenszustand befindet (nicht neu gestartet oder ausgeschaltet).

Wenn der Dienst mehr Zeit für die Bereinigung benötigt, sendet er STOP _ PENDING-Statusmeldungen zusammen mit einem Wartehinweis, damit der Dienstcontroller weiß, wie lange gewartet werden muss, bevor er dem System berichtet, dass das Herunterfahren des Diensts abgeschlossen ist. Um jedoch zu verhindern, dass ein Dienst das Herunterfahren beendet, gibt es eine Beschränkung für die Wartezeit des Dienstcontrollers. Wenn der Dienst über das Snap-In Dienste heruntergefahren wird, beträgt der Grenzwert 125 Sekunden oder 125.000 Millisekunden. Wenn das Betriebssystem neu gestartet wird, wird das Zeitlimit im WaitToKillServiceTimeout-Wert (in Millisekunden) des folgenden Registrierungsschlüssels angegeben:

HKEY _ LOCAL MACHINE SYSTEM _ \ \ CurrentControlSet-Steuerelement \

Wichtig

Ein Dienst sollte nicht versuchen, das Zeitlimit durch Ändern dieses Werts zu erhöhen. Wenn Sie WaitToKillServiceTimeout nicht von Hand festlegen müssen, sollte der Wert in Millisekunden sein.

Kunden benötigen ein schnelles Herunterfahren des Betriebssystems. Wenn beispielsweise ein Computer mit UPS-Stromversorgung das Herunterfahren nicht abschließen kann, bevor die USV nicht mehr voll ist, können Daten verloren gehen. Daher sollten Dienste ihre Bereinigungsaufgaben so schnell wie möglich ausführen. Es ist eine bewährte Methode, nicht gespeicherte Daten zu minimieren, indem Sie Daten regelmäßig speichern, die auf dem Datenträger gespeicherten Daten nachverfolgen und ihre nicht gespeicherten Daten nur beim Herunterfahren speichern. Da der Computer heruntergefahren wird, sollten Sie keine Zeit damit verbringen, zugewiesenen Arbeitsspeicher oder andere Systemressourcen frei zu geben. Wenn Sie einen Server benachrichtigen müssen, dass Sie den Dienst beenden, minimieren Sie die Zeit, die auf eine Antwort gewartet wird, da Netzwerkprobleme das Herunterfahren Ihres Diensts verzögern können.

Beachten Sie, dass der SCM beim Herunterfahren des Diensts standardmäßig keine Abhängigkeiten berücksichtigt. Der SCM listet die Liste der ausgeführten Dienste auf und sendet den Befehl SERVICE _ CONTROL _ SHUTDOWN. Daher kann ein Dienst fehlschlagen, da ein anderer Dienst, von dem er abhängig ist, bereits beendet wurde.

Erstellen Sie zum manuellen Festlegen der Reihenfolge des Herunterfahrens von Diensten einen Registrierungswert mit mehreren Zeichenfolgen, der die Dienstnamen in der Reihenfolge enthält, in der sie heruntergefahren werden sollen, und weisen Sie sie dem PreshutdownOrder-Wert des Steuerungsschlüssels wie folgt zu:

HKEY _ LOCAL _ MACHINE \ SYSTEM \ CurrentControlSet \ Control \ PreshutdownOrder="Shutdown Order"

Verwenden Sie die Funktion SetProcessShutdownParameters, um die Reihenfolge für das Herunterfahren abhängiger Dienste aus Ihrer Anwendung fest zu legen. Der SCM verwendet diese Funktion, um dem Handler 0x1E0 zu geben. Der SCM sendet SERVICE _ CONTROL SHUTDOWN-Benachrichtigungen, _ wenn sein Steuerungshandler aufgerufen wird, und wartet darauf, dass die Dienste beendet werden, bevor er von seinem Steuerelementhandler zurückkehrt.

Schreiben einer Steuerelementhandlerfunktion