Comment vérifier si un service Windows est installé en C #

J’ai écrit un service Windows qui expose un service WCF à une interface graphique installée sur le même ordinateur. Lorsque je lance l’interface graphique, si je ne parviens pas à me connecter au service, je dois savoir si l’application de service n’a pas encore été installée ou si le service n’est pas en cours d’exécution. Si le premier, je veux l’installer (comme décrit ici ); si ce dernier, je veux le démarrer.

La question est: comment détectez-vous si le service est installé, puis après avoir détecté qu’il est installé, comment le démarrez-vous?

Utilisation:

// add a reference to System.ServiceProcess.dll using System.ServiceProcess; // ... ServiceController ctl = ServiceController.GetServices() .FirstOrDefault(s => s.ServiceName == "myservice"); if(ctl==null) Console.WriteLine("Not installed"); else Console.WriteLine(ctl.Status); 

Vous pouvez également utiliser les éléments suivants.

 using System.ServiceProcess; ... var serviceExists = ServiceController.GetServices().Any(s => s.ServiceName == serviceName); 

En fait en boucle comme ceci:

 foreach (ServiceController SC in ServiceController.GetServices()) 

peut lancer une exception Access Denied si le compte sous lequel votre application s’exécute n’a pas le droit d’afficher les propriétés du service. D’autre part, vous pouvez le faire en toute sécurité, même si aucun service portant ce nom n’existe:

 ServiceController SC = new ServiceController("AnyServiceName"); 

Mais accéder à ses propriétés si le service n’existe pas entraînera une exception InvalidOperationException. Donc, voici un moyen sûr de vérifier si un service est installé:

 ServiceController SC = new ServiceController("MyServiceName"); bool ServiceIsInstalled = false; try { // actually we need to try access ANY of service properties // at least once to sortinggger an exception // not neccessarily its name ssortingng ServiceName = SC.DisplayName; ServiceIsInstalled = true; } catch (InvalidOperationException) { } finally { SC.Close(); } 

Pour les non-linq, vous pouvez simplement parcourir le tableau comme ceci:

 using System.ServiceProcess; bool serviceExists = false foreach (ServiceController sc in ServiceController.GetServices()) { if (sc.ServiceName == "myServiceName") { //service is found serviceExists = true; break; } } 
  private bool ServiceExists(ssortingng serviceName) { ServiceController[] services = ServiceController.GetServices(); var service = services.FirstOrDefault(s => ssortingng.Equals(s.ServiceName, serviceName, SsortingngComparison.OrdinalIgnoreCase)); return service != null; } 

Je pense que c’est la meilleure réponse à cette question. Il n’est pas nécessaire d’append un traitement supplémentaire pour vérifier si le service existe, car il générera une exception si ce n’est pas le cas. Vous avez juste besoin de l’attraper. Vous n’avez pas non plus besoin de fermer () la connexion si vous enveloppez la méthode entière en utilisant ().

 using (ServiceController sc = new ServiceController(ServiceName)) { try { if (sc.Status != ServiceControllerStatus.Running) { sc.Start(); sc.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 10)); //service is now Started } else //Service was already started } catch (System.ServiceProcess.TimeoutException) { //Service was stopped but could not restart (10 second timeout) } catch (InvalidOperationException) { //This Service does not exist } }