Wie bekomme ich Windows SCM, um meinen Dienst neu zu starten, wenn es fehlschlägt

8

Ich habe einige Windows-Dienste, die ich in Delphi geschrieben habe, und sie funktionieren im Allgemeinen sehr gut, aber gelegentlich bekomme ich eine Ausnahme, die als fatal angesehen werden kann. Wenn dies geschieht, ist der Dienst zum Stoppen eingerichtet.

Meine Frage ist, wie ich den Dienst so beenden kann, dass der SCM automatisch versucht, den Dienst neu zu starten. (Ich habe bereits die Wiederherstellungsoptionen für den Dienst im Service Manager festgelegt)

MSDN gibt

an
  

Ein Service wird als fehlgeschlagen betrachtet, wenn er beendet wird, ohne dem Service-Controller den Status SERVICE_STOPPED zu melden.

Ich habe diesen Blog-Beitrag gelesen Automatische Wiederherstellungsfunktionen der Windows-Dienste , aber ich bin mir nicht sicher, wie dies in Delphi implementiert wird.

ich habe bereits folgendes versucht

  • Festlegen der ErrCode-Eigenschaft des TService auf einen Wert ungleich Null.
  • Festlegen des gestoppten Parameters des ServiceStop-Ereignisses auf false.
  • Auslösen einer Ausnahme im servicestop-Ereignishandler.

EDIT 2013-08-06 Codebeispiel hinzugefügt

Code wurde jetzt aktualisiert, um ein funktionierendes Beispiel zu zeigen

Hier ist der Code, den ich benutze,

%Vor%

FFatalError ist ein privates boolesches Feld in der TTestService-Klasse und wird beim Start auf false initialisiert. Es wird nur auf true gesetzt, wenn der Worker-Thread (im TTestService.ServiceStart-Ereignis gestartet) mit einer schwerwiegenden Ausnahme beendet wird.

Hier ist der OnTerminate-Ereignishandler für den Arbeitsthread.

%Vor%     
MikeT 06.08.2013, 09:52
quelle

1 Antwort

8

Der SCM startet Ihren Dienst neu, wenn er fehlschlägt. Aber alle normalen Beendigungsmodi von einem Delphi-Dienst zählen nicht als Fehler . Wenn Sie eine Ausnahme vom Hauptdienstthread auslösen könnten, die nicht behandelt wurde, würde dies als Fehler gewertet werden.

Ich denke jedoch, dass der einfachste Weg für Sie, eine Prozessbeendigung zu erzwingen, die als Fehler behandelt wird, lautet ExitProcess . Sie könnten genauso gut die Delphi-RTL-Funktion Halt aufrufen, die letztendlich ExitProcess aufruft. Da Ihr Prozess jedoch wahrscheinlich in einem schlechten Zustand ist, würde ich direkt zu ExitProcess gehen.

Wie bereits erwähnt, wäre die Vermeidung der Ausnahme die ideale Lösung.

    
David Heffernan 06.08.2013, 13:18
quelle

Tags und Links