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 j'exécute L'interface graphique, si Je ne peux pas me connecter au service, j'ai besoin de savoir si c'est parce que l'application de service n'a pas encore été installée, ou si c'est parce que le service ne fonctionne pas. Si le premier, je veux l'installer (comme décrit ici ); si le second, 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?

68
demandé sur Community 2010-12-29 15:34:47

6 réponses

utiliser:

// 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);
126
répondu Aliostad 2013-07-22 21:16:06

vous pouvez aussi utiliser ce qui suit..

using System.ServiceProcess; 
... 
var serviceExists = ServiceController.GetServices().Any(s => s.ServiceName == serviceName);
33
répondu Simon Oliver Hurley 2013-02-25 14:10:59

en boucle comme ceci:

foreach (ServiceController SC in ServiceController.GetServices())

peut rejeter L'Accès refusé exception si le compte sous lequel votre application est en cours d'exécution n'a pas les droits de voir les propriétés de service. D'un autre côté, vous pouvez le faire en toute sécurité même s'il n'existe aucun service portant ce nom:

ServiceController SC = new ServiceController("AnyServiceName");

mais l'accès à ses propriétés si le service n'existe pas entraînera L'InvalidOperationException. Donc voici une façon sûre 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();
}
4
répondu Taosique 2014-02-06 09:41:06

pour non-linq, vous pouvez simplement itérer à 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;
    }
}
2
répondu ZTAN 2013-09-03 09:11:54
 private bool ServiceExists(string serviceName)
    {
        ServiceController[] services = ServiceController.GetServices();
        var service = services.FirstOrDefault(s => string.Equals(s.ServiceName, serviceName, StringComparison.OrdinalIgnoreCase));
        return service != null;
    }
1
répondu Ajaya Nayak 2016-04-27 07:49:43

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, car il lancera une exception s'il n'existe pas. Tu as juste besoin de l'attraper. Vous n'avez pas non plus besoin de fermer() la connexion si vous enveloppez toute 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       
 }     
}
-1
répondu bill 2014-06-12 15:02:02