46 votes

Vérifier si un service existe sur une machine particulière sans utiliser la gestion des exceptions

Ne sais pas si il y a une meilleure façon de le faire, c'est la raison pour laquelle la question. Je peux vérifier si un service n'existe que sur une machine en particulier avec le code suivant:

bool DoesServiceExist(string serviceName, string machineName)
{
    ServiceController controller = null;
    try
    {
        controller = new ServiceController(serviceName, machineName);
        controller.Status;
        return true;
    }
    catch(InvalidOperationException)
    {
        return false;
    }
    finally
    {
         if (controller != null)
         {
             controller.Dispose();
         }
    }
}

mais cela semble être une ineffecient solution pour moi (à cause de la gestion des exceptions). Est-il une meilleure façon de vérifier si un service existe. Remarque - j'ai récemment opté pour l' .Net 4.0, donc si quelqu'un sait d'une meilleure solution dans la version 4.0 qui seraient acceptables.

EDIT: Voici un exemple de c# console application pour tester les performances de mon exemple ainsi que les GetServices exemple de code. Dans mes tests, j'ai trouvé que le GetServices est beaucoup plus performatif dans le cas où le service n'existe pas, mais est deux fois plus lente lorsque le service n'existe pas:

    static void Main(string[] args)
    {
        string serviceName = string.Empty;
        string machineName = string.Empty;

        var sw = new Stopwatch();
        sw.Reset();
        sw.Start();
        for (int i = 0; i < 1000; i++)
        {
            ServiceExistsException(serviceName, machineName);
        }
        sw.Stop();
        Console.WriteLine("Elapsed time: " + sw.ElapsedMilliseconds.ToString());
        sw.Reset();
        sw.Start();
        for (int i = 0; i < 1000; i++)
        {
            ServiceExistsGetList(serviceName, machineName);
        }
        sw.Stop();
        Console.WriteLine("Elapsed time: " + sw.ElapsedMilliseconds.ToString());

        Console.WriteLine("Done");
        Console.ReadLine();
    }

    static bool ServiceExistsException(string serviceName, string machineName)
    {
        ServiceController controller = null;
        try
        {
            controller = new ServiceController(serviceName, machineName);
            string name = controller.DisplayName;
            return true;
        }
        catch (InvalidOperationException)
        {
            return false;
        }
        finally
        {
            if (controller != null)
            {
                controller.Dispose();
            }
        }
    }

    static bool ServiceExistsGetList(string serviceName, string machineName)
    {
        ServiceController[] services = null;
        try
        {
            services = ServiceController.GetServices(machineName);
            var service = services.FirstOrDefault(s => s.ServiceName == serviceName);
            return service != null;
        }
        finally
        {
            if (services != null)
            {
                foreach (ServiceController controller in services)
                {
                    controller.Dispose();
                }
            }
        }
    }
}

82voto

adrianbanks Points 36858

Vous pouvez utiliser l' ServiceController.GetServices() méthode pour obtenir tous les services sur la machine, puis regarder à travers eux pour voir si il en existe un, nommé à ce que vous recherchez:

bool DoesServiceExist(string serviceName, string machineName)
{
    ServiceController[] services = ServiceController.GetServices(machineName);
    var service = services.FirstOrDefault(s => s.ServiceName == serviceName);
    return service != null;
}

L' FirstOrDefault() méthode d'extension (à partir de System.Linq) sera de retour le premier service avec le prénom, ou un null si il n'y a pas de match.


Pour répondre à votre question de vitesse:

La différence entre les deux approches pour un seul appel de méthode est négligeable, peu importe si le service se trouve ou non. Il ne sera un problème si vous appelez cette méthode à des milliers de fois—dans ce cas, obtenir la liste des services une fois et s'en souvenir.

15voto

Mike Points 57

Même approche que adrianbanks mais un code légèrement plus compact. si vous utilisez linq, vous pouvez utiliser n'importe quelle instruction pour renvoyer ce que vous voulez. en outre, si vous vérifiez sur l'ordinateur local, pas besoin de donner le nom de l'ordinateur.

 bool DoesServiceExist(string serviceName)
{
   return ServiceController.GetServices().Any(serviceController => serviceController.ServiceName.Equals(serviceName));
}
 

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