Die Core Leute

Warning: This blog is not maintained any more (no update of content or links – as well as information are might deprecated / not valid any more).

Wie man einen Prozess als einen Service installieren kann

Unter verschiedene Umstände möchte man einen Prozess als Dienst installieren. In solch einem Fall wäre die erste Frage: ist der Prozess als Dienst gedacht?


 


·         Warum ist das wichtig, und wie funktioniert der Service Control Manager?


 


Ein Dienst ist erst einmal nicht ein einfacher Prozess. Um einen Prozess als Dienst zu installieren, muss der Prozess als Dienst gedacht und geschrieben werden.


Dienste werden durch den SCM (Service Control Manager) manipuliert (gestartet, gestoppt, für automatischen Start konfiguriert, eingestellt um unter einem bestimmten Konto ausgeführt zu werden, etc) und die Kommunikation mit den Diensten erfolgt auch durch den SCM.


Beim Versuch, einen Dienst zu starten, startet der SCM den Prozess auf welchen der Dienst zeigt durch die CreateProcessAsUser Funktion, startet den Prozess aber in einem suspendierten Status. Als nächstes erstellt der SCM ein pipe, durch welches es mit dem Prozess, unter welchem der Dienst läuft, kommuniziert.


Der SCM lässt den Prozess dann weiterlaufen, so dass sich dieser an das pipe verbinden kann. Der SCM wartet auf die Verbindung für eine bestimmte Zeit (standard 30 Sekunden, der Wert wird aber in der Registry definiert und kann geändert werden: ServicesPipeTimeout ). Wenn sich der Prozess nach der bestimmten Zeit nicht an das pipe verbindet, beendet der SCM den gestarteten Prozess.


 


So dass ein Prozess als Dienst installiert wird, muss dieser die entsprechenden Funktionen ins code implementiert haben, um mit dem SCM kommunizieren zu können.


Ansonsten wird beim Versuch den Dienst zu Starten ein time-out Fehler berichtet:


          The service did not respond to the start or control request in a timely fashion.


 


·         Wie wird der Prozess (der als Dienst gedacht wurde) als Dienst installiert?


 


Man kann:


a.       instsrv.exe (Resource Kit) benutzen:


Pfad\instsrv MyService Path\test.exe


 


b.      built-in sc.exe benutzen:


sc create MyService BinPath= „Path\test.exe” type= own


 


Dadurch wird der Dienst in services.msc hinzugefügt.


 


Gefilterter ProcMon output für sc create TestService BinPath= “C:\Windows\notepad.exe” type= own


7:36:44.6038125 PM      services.exe     528    RegOpenKey      HKLM\System\CurrentControlSet\services\TestService         NAME NOT FOUND       Desired Access: Read, Maximum Allowed


7:36:44.6038691 PM      services.exe     528    RegCreateKey    HKLM\System\CurrentControlSet\services\TestService                           SUCCESS       Desired Access: Read/Write


7:36:44.6042087 PM      services.exe     528    RegSetValue      HKLM\System\CurrentControlSet\services\TestService\Type                  SUCCESS       Type: REG_DWORD, Length: 4, Data: 16


7:36:44.6048827 PM      services.exe     528    RegSetValue      HKLM\System\CurrentControlSet\services\TestService\Start                  SUCCESS       Type: REG_DWORD, Length: 4, Data: 3


7:36:44.6053339 PM      services.exe     528    RegSetValue      HKLM\System\CurrentControlSet\services\TestService\ErrorControl      SUCCESS       Type: REG_DWORD, Length: 4, Data: 1


7:36:44.6056072 PM      services.exe     528    RegSetValue      HKLM\System\CurrentControlSet\services\TestService\ImagePath        SUCCESS       Type: REG_EXPAND_SZ, Length: 46, Data: C:\Windows\notepad.exe


7:36:44.6063459 PM      services.exe     528    RegSetValue       HKLM\System\CurrentControlSet\services\TestService\ObjectName     SUCCESS       Type: REG_SZ, Length: 24, Data: LocalSystem


 


c.       direkt in der Registry, manuell hinzufügen.


Wenn der Dienst in der Registry manuell hinzugefügt wird, muss das System neu gestartet werden, so dass die Änderungen erkannt werden.


Die empfohlene Methode ist aber den Dienst per sc.exe hinzuzufügen.


 


·         Wie kann man einen Prozess als Dienst installieren, wenn er nicht als Dienst gedacht wurde?


 


a. Das nötige code hinzufügenJ


b. Ein wrapper benutzen:


 


1.       Ein wrapper Prozess als Dienst installieren. Dadurch wird der wrapper Prozess gestartet.


srvany.exe (aus den Resource Kit Tools ) kann als wrapper benutzt werden:


sc create TestService BinPath= „Pfad\srvany.exe“ type=own


 


>sc query TestService


SERVICE_NAME: TestService


        TYPE               : 10  WIN32_OWN_PROCESS


        STATE              : 1  STOPPED


        WIN32_EXIT_CODE    : 1077  (0x435)


        SERVICE_EXIT_CODE  : 0  (0x0)


        CHECKPOINT         : 0x0


        WAIT_HINT          : 0x0


 


2.       Jetzt haben wir den wrapper Prozess als Dienst installiert.


Dieser ist nicht nur so gedacht, als Dienst installiert werden zu können und mit dem SCM zu kommunizieren. Dieser kann aber auch eine Application als Parameter kriegen und diese dann starten.


Er ist ja ein wrapper und ermöglicht die Kommunikation SCM > non-service Prozess, non-service Prozess > SCM für Start-Stop Aktionen


 


Wie wir das machen:


… in Regedit (Start > Run > Regedit) den Dienst finden: HKLM\System\CurrentControlSet\Services\TestService


… rechte Maustaste auf TestService > New > Key è Parameters nennen


… rechte Maustaste auf Parameters > New > String Value è Application nennen


… doppel-Klick auf Application und den Wert eintragen: PfadZurApplikation (in meinem Beispiel ist es c:\Windows\notepad.exe gewesen)


 


            Der Dienst kann jetzt gestartet warden:


>net start TestService


 


                Und so sieht der notepad.exe als Dienst aus (child Prozess für den wrapper srvany.exe)



1 


·         Recovery Optionen


Da der notepad.exe als child Prozess für den srvany.exe gestartet wird, können wir die Recovery Optionen nicht für den notepad.exe Prozess benutzen.


Die Recovery Optionen werden für den srvany.exe Prozess gültig sein:


… wenn der notepad.exe abstürzt, werden keine Aktionen aus den Recovery Optionen ausgeführt; srvany.exe wird weiter laufen.


… wenn der srvany.exe abstürzt, wird der notepad.exe (unser Dienst) Prozess weiter laufen (aber nicht mehr unter der services.exe Struktur), die Recovery Aktion wird aber ausgeführt.


Wenn wir „Restart the service“ als Recovery Aktion einstellen, wird der Dienst neu gestartet und hiermit eine 2te notepad.exe Instanz auch.


2



Rot     – Prozess der beendet wurde


Grün – neu gestartete Prozesse


 


Weitere Info zu dieses Thema:


KB137890 – How To Create a User-Defined Service


 


Viel Spaß beim Konfigurieren und Testen!J


 


Oni Sandru


Platforms Core Team