No sé si hay una mejor manera de hacerlo, por lo que ese es el motivo de la pregunta. Puedo comprobar si existe un servicio en una máquina en particular con el siguiente código:Compruebe si existe un servicio en una máquina en particular sin usar el manejo de excepciones
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();
}
}
}
pero esto parece una solución ineficiente para mí (debido al manejo de excepciones). ¿Hay una mejor manera de verificar si existe un servicio? Nota: Recientemente cambié a .Net 4.0, por lo que si alguien sabe de una solución mejor en 4.0 sería aceptable.
EDIT: Aquí hay una aplicación de consola C# para probar el rendimiento de mi ejemplo, así como el ejemplo del código GetServices. En mis pruebas encontré que los GetServices es mucho más performativo en el caso en que no existe el servicio, pero es dos veces más lento cuando el servicio no existe:
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();
}
}
}
}
}
Me resultó cuestionable el rendimiento de su solución, por lo que realicé una prueba. Su solución es mucho más performativa (incluso con el código agregado para eliminar los controladores de servicio) cuando el servicio no existe. En el caso donde el servicio existe, esta solución es dos veces más lenta. No estoy seguro de qué hacer ahora. En mi caso, espero que la mayoría de las veces el servicio exista. En ese caso, mi solución gana, en el caso más genérico, su solución gana. – pstrjds
Un comentario adicional. Básicamente, esta solución se ejecuta en tiempo constante, ya sea que el servicio exista o no. Felicitaciones por una buena solución de caso genérico. – pstrjds
En respuesta al problema de velocidad, el código que presenté en la pregunta es más rápido cuando el servicio existe (aunque estoy de acuerdo en que es insignificante). Normalmente no estaría llamando esto en un bucle (simplemente lo hice para el análisis de rendimiento), de lo contrario podría almacenar en caché la lista. Creo que el éxito está en iterar la lista dos veces. Una vez para encontrar el servicio (aunque no necesariamente una iteración completa de toda la lista) y otro momento para deshacerse de los objetos. En el caso en que estoy implementando, no puedo almacenar en caché la lista, puedo ejecutar la función con días de diferencia, en cuyo caso el servicio podría haberse eliminado. – pstrjds