144 votes

Comment un service Windows peut-il se redémarrer de manière programmatique ?

Je dois écrire un code robuste en .NET pour permettre à un service Windows (serveur 2003) de se redémarrer lui-même. Quelle est la meilleure façon de le faire ? Existe-t-il une API .NET pour le faire ?

7 votes

"Robuste" est un mot-clé ( stackoverflow.fogbugz.com/default.asp?W13086 ) - quelles sont les caractéristiques spécifiques dont vous avez besoin ?

201voto

TheSoftwareJedi Points 15921

Configurez le service pour qu'il redémarre après un échec (double-cliquez sur le service dans le panneau de configuration et regardez dans ces onglets - j'ai oublié le nom). Ensuite, à chaque fois que vous voulez que le service redémarre, appelez simplement Environment.Exit(1) (ou tout autre retour non nul) et le système d'exploitation le redémarrera pour vous.

0 votes

Les solutions simples sont les meilleures solutions. Je l'ai juste fait pour remplacer la configuration existante de "2ème processus pour redémarrer périodiquement le premier".

8 votes

Pour info, l'emplacement se trouve dans le panneau des services, faites un clic droit sur le service en question et sélectionnez les propriétés, puis choisissez l'onglet de récupération.

20 votes

Je vois comment cela permet d'obtenir le comportement souhaité, mais un code de retour de 1 est censé indiquer au système qu'il y a eu une erreur. N'est-ce pas une mauvaise pratique s'il n'y avait en fait aucune erreur et que vous vouliez simplement redémarrer votre service ?

23voto

Khalid Rahaman Points 865
Dim proc As New Process()
Dim psi As New ProcessStartInfo()

psi.CreateNoWindow = True
psi.FileName = "cmd.exe"
psi.Arguments = "/C net stop YOURSERVICENAMEHERE && net start YOURSERVICENAMEHERE"
psi.LoadUserProfile = False
psi.UseShellExecute = False
psi.WindowStyle = ProcessWindowStyle.Hidden
proc.StartInfo = psi
proc.Start()

3 votes

N'oubliez pas d'ajouter " " autour de votre nom de service s'il contient des espaces.

4 votes

Cela ne concerne que les services fonctionnant sous un compte privilégié, ce qui est de toute façon une mauvaise idée.

2 votes

En fonction de votre environnement, vous devrez peut-être vous assurer que le processus cmd.exe s'exécute dans un groupe de processus distinct. J'ai essayé d'implémenter ceci, mais le processus enfant cmd.exe mourait à chaque fois que "net stop" était exécuté. Pour éviter cela, vous devez appeler CreateProcess en spécifiant CREATE_NEW_PROCESS_GROUP.

18voto

Greg Hewgill Points 356191

Vous ne pouvez pas être sûr que le compte d'utilisateur sous lequel votre service est exécuté a même les autorisations nécessaires pour arrêter et redémarrer le service.

0 votes

Bien que +1-ed car j'ai été confronté au même problème, en regardant sc.exe il s'avère qu'il utilise SERVICE_QUERY_CONFIG comme dwDesiredAccess lors de l'appel à OpenSCManager () et ensuite appelle OpenService() avec SERVICE_START | SERVICE_STOP pour ouvrir un service particulier et cela fonctionne bien (pas de problème d'accès). Je ne suis pas sûr de savoir comment cela peut être fait en .NET.

0 votes

La plupart des services Windows s'exécutent en tant que système, ce qui ne devrait pas poser de problème.

0 votes

@Switch il y a un grand cercle de services qui sont exécutés sous NETWORK SERVICE, qui par défaut n'a même pas le droit d'ouvrir son propre exécutable.

14voto

Filip Points 952
const string strCmdText = "/C net stop \"SERVICENAME\"&net start \"SERVICENAME\"";
Process.Start("CMD.exe", strCmdText);

SERVICENAME est le nom de votre service (les guillemets sont inclus pour tenir compte des espaces dans le nom du service, ils peuvent être omis autrement).

Propre, aucune configuration de redémarrage automatique nécessaire.

10 votes

J'ai appris quelque chose de nouveau sur & vs && : [command1] & [command2] exécutera toujours les deux commandes séquentiellement, alors que [command1] && [command2] n'exécute la commande2 que si la commande1 s'exécute avec succès ( autoitscript.com/forum/topic/ )

5voto

Brody Points 1859

Cela dépend de la raison pour laquelle vous voulez qu'il redémarre lui-même.

Si vous cherchez simplement un moyen de faire en sorte que le service se nettoie lui-même périodiquement, vous pourriez faire tourner une minuterie dans le service qui déclenche périodiquement une routine de purge.

Si vous cherchez un moyen de redémarrer en cas d'échec, l'hôte de service lui-même peut offrir cette possibilité lorsqu'il est configuré.

Alors pourquoi devez-vous redémarrer le serveur ? Qu'est-ce que vous essayez d'obtenir ?

1 votes

Cela ne fonctionnerait pas si vous êtes concerné par le Large Object Heap et la fragmentation de la mémoire. On dit que .NET 4/4.5 et les processus 64 bits ont beaucoup aidé à résoudre ce problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X