77 votes

Comment vérifier si un service windows est installé dans C#

J'ai écrit un Service Windows qui expose un service WCF à une interface graphique installée sur la même machine. Quand je lance l'interface graphique, si je ne peux pas se connecter au service, j'ai besoin de savoir si c'est parce que l'application de service n'a pas encore été installé, ou si c'est parce que le service n'est pas en cours d'exécution. Dans le premier cas, je vais vouloir l'installer (comme décrit ici); dans ce dernier cas, je veux le démarrer.

La Question est: comment détecter si le service est installé, puis après avoir détecté qu'il est installé, comment voulez-vous commencer?

141voto

Aliostad Points 47792

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);

35voto

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

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

6voto

Taosique Points 1904

En fait en boucle comme ceci:

foreach (ServiceController SC in ServiceController.GetServices())

peut jeter Accès Refusé exception si le compte sous lequel votre application est en cours d'exécution n'a pas les droits pour afficher les propriétés du service. D'autre part, vous pouvez faire en toute sécurité et ce, même si aucun service avec un tel nom existent:

ServiceController SC = new ServiceController("AnyServiceName");

Mais l'accès à ses propriétés si le service n'existe pas en résultera InvalidOperationException. Voici donc 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 trigger an exception
    // not neccessarily its name
    string ServiceName = SC.DisplayName;
    ServiceIsInstalled = true;
}
catch (InvalidOperationException) { }
finally
{
    SC.Close();
}

2voto

Jing Points 56

Pour les non-linq, vous pouvez simplement effectuer une itération à travers 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;
    }
}

0voto

bill Points 143

Je pense que c'est la meilleure réponse à cette question. Il n'est pas nécessaire d'ajouter un traitement supplémentaire pour vérifier si le service existe, puisqu'il va lever une exception si elle ne le fait pas. Vous avez juste besoin de l'attraper. Vous aussi n'avez pas besoin de fermer() la connexion si vous envelopper l'ensemble de la méthode 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       
 }     
}

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