Ich muss robusten Code in .NET schreiben, damit ein Windows-Dienst (Server 2003) sich selbst neu starten kann. Was ist der beste Weg dazu? Gibt es eine .NET-API dafür?
.net
windows
windows-services
windows-server-2003
Ron Harlev
quelle
quelle
Antworten:
Stellen Sie den Dienst so ein, dass er nach einem Fehler neu gestartet wird (doppelklicken Sie auf den Dienst in der Systemsteuerung und sehen Sie sich auf diesen Registerkarten um - ich habe den Namen vergessen). Wenn Sie dann möchten, dass der Dienst neu gestartet wird, rufen Sie einfach an
Environment.Exit(1)
(oder eine Rückgabe ungleich Null), und das Betriebssystem startet ihn für Sie neu.quelle
Service.ExitCode = 1
und dann ausführenService.Stop()
. Wenn Sie dies auf diese Weise tun, wird das System ordnungsgemäß heruntergefahren und der Neustart ausgelöst.quelle
Sie können nicht sicher sein, ob das Benutzerkonto, unter dem Ihr Dienst ausgeführt wird, überhaupt die Berechtigung hat, den Dienst zu stoppen und neu zu starten.
quelle
Sie können einen Prozess erstellen, bei dem es sich um eine DOS-Eingabeaufforderung handelt, die sich selbst neu startet:
quelle
Wo
SERVICENAME
ist der Name Ihres Dienstes (doppelte Anführungszeichen, um Leerzeichen im Dienstnamen zu berücksichtigen, können ansonsten weggelassen werden).Sauber, keine automatische Neustartkonfiguration erforderlich.
quelle
Es hängt davon ab, warum Sie möchten, dass es sich selbst neu startet.
Wenn Sie nur nach einer Möglichkeit suchen, den Dienst regelmäßig selbst zu bereinigen, wird möglicherweise ein Timer im Dienst ausgeführt, der regelmäßig eine Bereinigungsroutine verursacht.
Wenn Sie nach einer Möglichkeit suchen, bei einem Fehler neu zu starten, kann der Service-Host diese Funktion beim Einrichten bereitstellen.
Warum müssen Sie den Server neu starten? Was versuchst du zu erreichen?
quelle
Ich glaube nicht, dass Sie dies in einem eigenständigen Dienst tun können (wenn Sie Restart aufrufen, wird der Dienst gestoppt, wodurch der Befehl Restart unterbrochen wird und er wird nie wieder gestartet). Wenn Sie eine zweite EXE-Datei hinzufügen können (eine Konsolen-App, die die ServiceManager-Klasse verwendet), können Sie die eigenständige EXE-Datei starten, den Dienst neu starten und dann beenden.
Beim zweiten Gedanken könnte der Dienst wahrscheinlich eine geplante Aufgabe registrieren lassen (z. B. über den Befehlszeilenbefehl 'at'), um den Dienst zu starten und ihn dann selbst stoppen zu lassen. das würde wahrscheinlich funktionieren.
quelle
Das Problem beim Auslagern in eine Batchdatei oder EXE besteht darin, dass ein Dienst möglicherweise über die zum Ausführen der externen App erforderlichen Berechtigungen verfügt oder nicht.
Der sauberste Weg, dies zu tun, ist die OnStop () -Methode, die der Einstiegspunkt für den Service Control Manager ist. Dann wird Ihr gesamter Bereinigungscode ausgeführt, und Sie haben keine hängenden Sockets oder andere Prozesse, vorausgesetzt, Ihr Stoppcode erledigt seine Aufgabe.
Dazu müssen Sie vor dem Beenden ein Flag setzen, das die OnStop-Methode anweist, mit einem Fehlercode zu beenden. dann weiß der SCM, dass der Dienst neu gestartet werden muss. Ohne dieses Flag können Sie den Dienst nicht manuell vom SCM aus stoppen. Dies setzt auch voraus, dass Sie den Dienst so eingerichtet haben, dass er bei einem Fehler neu gestartet wird.
Hier ist mein Stoppcode:
Wenn der Dienst auf ein Problem stößt und neu gestartet werden muss, starte ich einen Thread, der den Dienst vom SCM stoppt. Dies ermöglicht es dem Dienst, nach sich selbst aufzuräumen:
quelle
Ich würde den Windows Scheduler verwenden, um einen Neustart Ihres Dienstes zu planen. Das Problem ist, dass Sie sich nicht neu starten können, aber Sie können sich selbst stoppen. (Sie haben im Wesentlichen den Ast abgesägt, auf dem Sie sitzen ... wenn Sie meine Analogie verstehen.) Sie benötigen einen separaten Prozess, um dies für Sie zu tun. Der Windows Scheduler ist geeignet. Planen Sie eine einmalige Aufgabe, um Ihren Dienst (auch innerhalb des Dienstes selbst) neu zu starten und sofort auszuführen.
Andernfalls müssen Sie einen "Hirten" -Prozess erstellen, der dies für Sie erledigt.
quelle
Die erste Antwort auf die Frage ist die einfachste Lösung: "Environment.Exit (1)" Ich verwende dies unter Windows Server 2008 R2 und es funktioniert perfekt. Der Dienst stoppt sich selbst, das Betriebssystem wartet 1 Minute und startet es dann neu.
quelle
Ich glaube nicht, dass es geht. Wenn ein Dienst "gestoppt" wird, wird er vollständig entladen.
Okay, ich nehme an, es gibt immer einen Weg. Sie können beispielsweise einen getrennten Prozess erstellen, um den Dienst zu stoppen, ihn dann neu zu starten und dann zu beenden.
quelle
Der bessere Ansatz könnte darin bestehen, den NT-Dienst als Wrapper für Ihre Anwendung zu verwenden. Wenn der NT-Dienst gestartet wird, kann Ihre Anwendung in einem "Leerlauf" -Modus gestartet werden, der auf den Start des Befehls wartet (oder so konfiguriert sein, dass er automatisch gestartet wird).
Denken Sie an ein Auto, wenn es gestartet wird, beginnt es im Leerlauf und wartet darauf, dass Ihr Befehl vorwärts oder rückwärts geht. Dies bietet auch andere Vorteile, z. B. eine bessere Remoteverwaltung, da Sie auswählen können, wie Ihre Anwendung verfügbar gemacht werden soll.
quelle
Gerade vorbei: und dachte, ich würde ein paar zusätzliche Informationen hinzufügen ...
Sie können auch eine Ausnahme auslösen. Dadurch wird der Windows-Dienst automatisch geschlossen, und die Optionen für den automatischen Neustart werden aktiviert. Das einzige Problem dabei ist, dass die JIT versucht, den PC einzuschalten, wenn Sie eine Entwicklungsumgebung auf Ihrem PC haben. und Sie erhalten eine Eingabeaufforderung mit der Meldung Debug J / N. Sagen Sie Nein, und dann wird es geschlossen und dann ordnungsgemäß neu gestartet. (Auf einem PC ohne JIT funktioniert einfach alles). Der Grund für das Trolling ist, dass diese JIT neu in Win 7 ist (sie funktionierte früher einwandfrei mit XP usw.) und ich versuche, eine Möglichkeit zu finden, die JIT zu deaktivieren. Ich kann die hier erwähnte Environment.Exit-Methode ausprobieren das funktioniert auch
Kristian: Bristol, Großbritannien
quelle
Erstellen Sie eine restart.bat-Datei wie diese
Löschen Sie dann die Aufgabe% taskname%, wenn Ihr% service% gestartet wird
quelle
Erstellen Sie eine separate Appdomain, um den Anwendungscode zu hosten. Wenn ein Neustart erforderlich ist, können wir die App-Domäne anstelle des Prozesses (Windows-Dienst) entladen und neu laden. So funktioniert der IIS-App-Pool. Sie führen die asp.net-App nicht direkt aus, sondern verwenden einen separaten Appdmain.
quelle
Am einfachsten ist es, eine Batch-Datei zu haben mit:
net stop net start
und fügen Sie die Datei mit dem gewünschten Zeitintervall zum Scheduler hinzu
quelle
quelle