wake-up-neo.com

So deinstallieren Sie einen Windows-Dienst und löschen seine Dateien ohne einen Neustart

Mein aktuelles Projekt beinhaltet die Bereitstellung einer aktualisierten EXE-Datei, die als Windows-Dienst ausgeführt wird. Um die vorhandene .exe-Datei mit der neuen Version zu überschreiben, muss ich derzeit Folgendes tun:

  1. Stoppen Sie den Dienst
  2. Deinstallieren Sie den Dienst
  3. Starten Sie das System neu (damit Windows-Versionen die Datei halten)
  4. Stellen Sie die neue EXE-Datei bereit
  5. Installieren Sie den Dienst neu
  6. Starten Sie den aktualisierten Dienst.

Ich möchte den Neustart vermeiden, so dass dies ein vollständig skriptbasiertes/automatisiertes Upgrade sein kann.

Gibt es eine Möglichkeit, einen Neustart zu vermeiden? Vielleicht ein Befehlszeilentool, das Windows dazu zwingt, die alte .exe-Instanz aufzugeben?

44
Nate Sauber
sc delete "service name"

löscht einen Dienst. Ich finde, dass das sc-Dienstprogramm viel einfacher zu finden ist, als nach installutil zu suchen. Denken Sie daran, den Dienst zu beenden, falls Sie dies nicht bereits getan haben.

77
StingyJack

Können Sie den Dienst nicht vor dem Update beenden (und nach dem Update neu starten), indem Sie die folgenden Befehle verwenden?

net stop <service name>
net start <service name>

Wenn ich einen Dienst teste/bereitstelle, kann ich Dateien hochladen, ohne dass eine Neuinstallation erforderlich ist, solange der Dienst angehalten ist. Ich bin nicht sicher, ob das Problem, das Sie haben, anders ist.

14
Jonathan S.

Ich hatte irgendwie das gleiche Problem wie du. Ich habe einen Systemdienst, den ich deinstallieren und anschließend als Teil eines Updates neu installieren möchte. Auf bestimmten Systemen würde dies ohne Neustart nicht funktionieren. Das Problem war, dass ein Aufruf von DeleteService () ok zurückgegeben wurde. Der folgende Aufruf von CreateService () würde mich jedoch darauf hinweisen, dass der Dienst noch vorhanden war, jedoch zum Löschen markiert wurde (Fehlercode 1072). Die Registrierung würde berücksichtigen, dass der Unterschlüssel noch vorhanden war (unter HKLM\System\CurrentControlSet\Services), aber "DeleteFlag" auf 1 gesetzt wurde. Ab diesem Zeitpunkt konnte nur ein Neustart die Situation beheben.

Einige Dinge, die nicht funktionieren:

  • Verwenden von "sc delete": Es hatte die gleichen Probleme wie ich. Der Aufruf würde in Ordnung zurückkehren, der Dienst war jedoch nicht wirklich weg und befindet sich noch immer in der Registrierung mit DeleteFlag = 1.
  • Löschen des Schlüssels in der Registrierung. Der Service Manager scheint eine Datenbank im Arbeitsspeicher zu halten, und die Registrierung ist nur eine Kopie davon für den nächsten Start.
  • Warteschleifen hinzufügen, darauf warten, dass EXE-Dateien überschrieben werden, den Prozess abbrechen, usw. 
  • Schließpunkte zum Dienst. Welche??

Aber hier ist was funktioniert: 

Ich habe in einigen Artikeln hier über stackoverflow festgestellt, dass net.exe auch Start/Stopp-Funktionen hat (ich wusste nur von sc.exe). Und seltsamerweise funktionierte ein "net stop svcname" plus ein "sc delete svcname"! Net.exe muss also etwas tun, was ich nicht mache.

Net.exe enthält jedoch keinen Import in ControlService (). Wie kann der Dienst angehalten werden? Ich habe herausgefunden, dass net.exe net1.exe erzeugt, aber net1.exe importiert auch nicht ControlService (). Ich habe das großartige API Monitor-Dienstprogramm ( http://www.rohitab.com/apimonitor ) verwendet, um zu sehen, was net1.exe macht, aber es hat nie etwas genannt, das vielversprechend aussah.

Aber dann habe ich gesehen, dass es NetServiceControl () aus NETAPI32.DLL importiert (das mindestens "Service" im Namen hatte!). MSDN sagt, dass diese Funktion veraltet ist. Trotzdem fand ich den Prototyp in LMSvc.h und einige Parameterbeschreibungen hier: http://cyberkinetica.homeunix.net/os2tk45/srvfpgr/369_L2_NetServiceControlorN.html . Wenn Sie NETAPI32.DLL laden und NetServiceControl(NULL, service_name, 3, 0, 0) verwenden (3 steht für SERVICE_CTRL_UNINSTALL, das zum Beenden verwendet wird), wird der Dienst danach angehalten. Und es kann gelöscht und anschließend ohne DeleteFlag oder Neustart erneut installiert werden!

Es war also nie ein Problem zu löschen, sondern den Dienst ordnungsgemäß zu stoppen. Und NetServiceControl () macht den Trick. Sorry für den langen Beitrag, aber ich dachte, es könnte jemandem mit ähnlichen Problemen helfen. (Nur als Referenz verwende ich Win7 SP1 x64.)

14
cxxl

Wenn in .net (Ich bin nicht sicher, ob es für alle Windows-Dienste funktioniert)

  • Beenden Sie den Dienst (möglicherweise liegt ein Problem vor.)
  • InstallUtil -u [Name der ausführbaren Datei]
  • Installutil -i [Name der ausführbaren Datei]
  • Starten Sie den Dienst erneut ...

Wenn ich nicht die öffentliche Benutzeroberfläche des Dienstes ändere, setze ich häufig aktualisierte Versionen meiner Dienste ein, ohne die Deinstallation/Deinstallation des Programms zu beenden. 

3
Charles Bretana

Wie von StingyJack und mcbala bemerkt, und in Bezug auf die Kommentare von Mike L, ist meine Erfahrung, dass auf einem Windows 2000-Rechner beim Deinstallieren/Neuinstallieren von .NET-Diensten "installutil/u" do sogar einen Neustart erfordert wenn der Dienst zuvor gestoppt wurde. "sc/delete" hingegen erfordert keinen Neustart - es löscht den Dienst sofort (solange er angehalten ist).

Ich habe mich oft gefragt, ob es einen guten Grund gibt, dass "installutil/u" einen Neustart erfordert ... Ist "sc/delete" tatsächlich etwas falsches/lässt etwas hängen?

3
Tao

(Windows-Versionen halten also die -Datei fest)

Führen Sie stattdessen Strg + Alt + Entf direkt nach dem Beenden des Diensts aus, und beenden Sie die .exe des Dienstes. Dann können Sie den Dienst ohne Neustart deinstallieren. Dies ist mir in der Vergangenheit passiert und löst den Teil, den Sie zum Neustart benötigen.

2

Sollte es notwendig sein, einen Dienst manuell zu entfernen:

  1. Führen Sie Regedit oder Regedt32 aus.
  2. Suchen Sie den Registrierungsschlüsseleintrag für Ihren Dienst unter folgendem Schlüssel: HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services
  3. Löschen Sie den Registrierungsschlüssel

Sie müssen einen Neustart durchführen, bevor die Liste in den Diensten aktualisiert wird

2
chrishawn

Sowohl Jonathan als auch Charles haben recht ... Sie müssen zuerst den Dienst beenden und dann deinstallieren/neu installieren. Die Kombination der beiden Antworten ergibt die perfekte Batchdatei oder das PowerShell-Skript.

Ich möchte auf eine hart erlernte Vorsicht hinweisen - Windows 2000 Server (möglicherweise auch das Client-Betriebssystem) erfordert vor der Neuinstallation einen Neustart, egal was passiert. Es muss einen Registrierungsschlüssel vorhanden sein, der nicht vollständig gelöscht wird, bis die Box neu gestartet wird. Windows Server 2003, Windows XP und spätere Betriebssystemversionen leiden nicht unter diesen Schmerzen.

2
Mike L

Ich verwende die mit .NET Framework gepackte InstallUtil.exe.

Die zu deinstallierende Anwendung ist: InstallUtil '\ path\to\Assembly\mit\the\installer\classes'/u, zum Beispiel: installutil MyService.HostService.exe /u

Der /u-Schalter steht für uninstall, ohne dass der Benutzer eine normale Installation des Dienstes durchführt. Das Dienstprogramm stoppt den Dienst, wenn er ausgeführt wird, und ich hatte nie Probleme mit der Sperrung der Dienstdateien durch Windows. Weitere Optionen von InstallUtil finden Sie unter MSDN .

PS: Wenn Sie nicht installutil in Ihrer Pfadvariablen haben, verwenden Sie den vollständigen Pfad wie folgt: C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe "C:\MyServiceFolder\MyService.HostService.exe" /u oder wenn Sie eine 64-Bit-Version benötigen, finden Sie sie unter 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319 \' .The Die Versionsnummer im Pfad hängt von der .NET-Version ab.

0
MSkuta