web-dev-qa-db-fra.com

Comment désinstaller un service Windows et supprimer ses fichiers sans redémarrer

Mon projet actuel implique le déploiement d'un fichier .exe mis à niveau qui s'exécute en tant que service Windows. Pour écraser le fichier .exe existant avec la nouvelle version, je dois actuellement:

  1. Arrêtez le service
  2. Désinstaller le service
  3. Redémarrez le système (donc Windows publie sa mise en attente sur le fichier)
  4. Déployer le nouveau fichier .exe
  5. Réinstaller le service
  6. Démarrer le service mis à niveau.

J'aimerais éviter le redémarrage, afin que cela puisse être une mise à niveau entièrement scriptée/automatisée.

Est-il possible d'éviter de redémarrer? Peut-être un outil de ligne de commande qui forcera Windows à abandonner son emprise mortelle sur l'ancien fichier .exe?

44
Nate Sauber
sc delete "service name"

va supprimer un service. Je trouve que l'utilitaire sc est beaucoup plus facile à localiser que de chercher pour installutil. N'oubliez pas d'arrêter le service si vous ne l'avez pas déjà fait.

77
StingyJack

Ne pouvez-vous pas arrêter le service avant la mise à jour (et le redémarrer après la mise à jour) à l'aide des commandes ci-dessous?

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

Chaque fois que je teste/déploie un service, je peux télécharger des fichiers sans réinstaller tant que le service est arrêté. Je ne sais pas si le problème que vous rencontrez est différent.

14
Jonathan S.

J'ai en quelque sorte le même problème que vous. J'ai un service système que je veux désinstaller puis réinstaller dans le cadre d'une mise à jour. Sur certains systèmes, cela ne fonctionnerait pas sans un redémarrage. Le problème était qu'un appel à DeleteService () retournerait ok, mais l'appel suivant à CreateService () me dirait que le service était toujours là, mais qu'il était marqué pour suppression (code d'erreur 1072). Le registre refléterait que, puisque la sous-clé était toujours là (sous HKLM\System\CurrentControlSet\Services), mais que "DeleteFlag" avait la valeur 1. À partir de ce moment-là, seul un redémarrage pourrait résoudre le problème.

Certaines choses qui ne fonctionnent pas:

  • Utilisation de "sc delete": cela posait les mêmes problèmes que moi. L’appel reviendrait bien, mais le service n’était pas vraiment parti et restait dans le registre avec DeleteFlag = 1.
  • Suppression de la clé dans le registre. Le gestionnaire de service semble conserver une base de données en mémoire et le registre n'en est qu'une copie pour le prochain démarrage.
  • Ajouter des boucles d'attente, attendre que les fichiers .exe soient prêts à être écrasés, tuer le processus, etc. 
  • Fermeture des poignées du service. Lesquels??

Mais voici ce qui a fonctionné: 

J'ai remarqué dans certains articles sur stackoverflow que net.exe possède également des fonctionnalités de démarrage/d'arrêt (je ne connaissais que l'utilitaire sc.exe). Et étrangement, un "net stop svcname" plus un "sc delete svcname" ont fonctionné! Donc net.exe doit faire quelque chose que je ne fais pas.

Mais net.exe ne contient pas d’importation dans ControlService (). Comment arrêter le service? J'ai découvert que net.exe génère net1.exe, mais net1.exe n'importe pas non plus ControlService (). J'ai utilisé le formidable utilitaire API Monitor ( http://www.rohitab.com/apimonitor ) pour voir ce que fait net1.exe, mais il n'a jamais appelé quoi que ce soit qui semblait prometteur.

Mais ensuite, j'ai constaté qu'il importait NetServiceControl () à partir de NETAPI32.DLL (qui avait au moins "Service" dans son nom!). MSDN indique que cette fonction est obsolète. Néanmoins, j'ai trouvé le prototype dans LMSvc.h et une description de paramètre ici: http://cyberkinetica.homeunix.net/os2tk45/srvfpgr/369_L2_NetServiceControlorN.html . Lorsque vous chargez NETAPI32.DLL et utilisez la fonction NetServiceControl(NULL, service_name, 3, 0, 0) (3 correspond à SERVICE_CTRL_UNINSTALL utilisé pour arrêter), le service est arrêté par la suite. Et il peut être supprimé et réinstallé par la suite sans DeleteFlag ou redémarrage!

Il n’a donc jamais été question de supprimer, mais d’arrêter correctement le service. Et NetServiceControl () fait le tour. Désolé pour le long post, mais je pensais que cela pourrait aider quelqu'un avec des problèmes similaires. (Juste pour référence, j'utilise Win7 SP1 x64.)

14
cxxl

Si vous êtes en .net (je ne sais pas si cela fonctionne pour tous les services Windows)

  • Arrêtez le service (c’est peut-être pour cette raison que vous rencontrez un problème.)
  • InstallUtil -u [nom de l'exécutable]
  • Installutil -i [nom de l'exécutable]
  • Recommencez le service ...

Sauf si je modifie l'interface publique du service, je déploie souvent des versions mises à niveau de mes services sans même annuler la désinstallation/la réinstallation ... Tout ce que je fais, c'est arrêter le service, remplacer les fichiers et redémarrer le service ... 

3
Charles Bretana

Comme noté par StingyJack et mcbala, et en référence aux commentaires de Mike L, mon expérience est que sur une machine Windows 2000, lors de la désinstallation/réinstallation des services .Net, "installutil/u" nécessite nécessite un redémarrage, même lorsque le service a été précédemment arrêté. "sc/delete", en revanche, ne nécessite pas de redémarrage - il supprime immédiatement le service (tant qu'il est arrêté).

En fait, je me suis souvent demandé s'il y avait une bonne raison pour que "installutil/u" nécessite un redémarrage ... Est-ce que "sc/delete" fait vraiment quelque chose de mal/laisse quelque chose en suspens?

3
Tao

(Windows est donc mis en attente sur le fichier )

Au lieu de cela, faites Ctrl + Alt + Suppr juste après l’arrêt du service et tuez le fichier .exe du service. Ensuite, vous pouvez désinstaller le service sans redémarrer. Cela m'est arrivé dans le passé et cela résout le problème que vous devez redémarrer.

2
Patrick Desjardins

S'il est nécessaire de supprimer manuellement un service:

  1. Exécutez Regedit ou regedt32.
  2. Recherchez l'entrée de clé de registre de votre service sous la clé suivante: HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services
  3. Supprimer la clé de registre

Vous devrez redémarrer avant que la liste ne soit mise à jour dans les services

2
chrishawn

Jonathan et Charles ont raison. Il faut d’abord arrêter le service, puis désinstaller/réinstaller. La combinaison de leurs deux réponses constitue le fichier de commandes parfait ou le script PowerShell.

Je vais mentionner une mise en garde apprise à la dure - Windows 2000 Server (éventuellement le système d'exploitation client également) nécessitera un redémarrage avant la réinstallation, quoi qu'il arrive. Il doit y avoir une clé de registre qui n'est pas complètement effacée jusqu'au redémarrage de la boîte. Windows Server 2003, Windows XP et les versions ultérieures du système d'exploitation ne souffrent pas de cette douleur.

2
Mike L

J'utilise InstallUtil.exe fourni avec .NET Framework.

L'utilisation à désinstaller est la suivante: InstallUtil '\ chemin\to\Assembly\avec\l'installeur\classes'/u ainsi, par exemple: installutil MyService.HostService.exe /u

Le commutateur /u signifie désinstaller, sans lui, util effectue l’installation normale du service. L'utilitaire arrête le service s'il est en cours d'exécution et je n'ai jamais eu de problèmes avec le verrouillage de Windows sur les fichiers de service. Vous pouvez en savoir plus sur les autres options d’InstallUtil sur MSDN .

PS: si vous n’avez pas installutil dans votre variable de chemin, utilisez le chemin complet comme ceci: C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe "C:\MyServiceFolder\MyService.HostService.exe" /u ou si vous avez besoin d’une version 64 bits, vous pouvez le trouver dans 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319 \'. Le numéro de version dans le chemin varie en fonction de la version .NET.

0
MSkuta