2008-10-07 39 views
150

Tengo una aplicación en C# (2.0 ejecutándose en XP incrustado) que se está comunicando con un 'watchdog' implementado como un servicio de Windows. Cuando se inicia el dispositivo, este servicio normalmente tarda un poco en comenzar. Me gustaría verificar, desde mi código, si el servicio se está ejecutando. ¿Cómo puedo lograr esto?¿Cómo puedo verificar si se está ejecutando un servicio de Windows?

Respuesta

290

supongo que algo como esto funcionaría:

Añadir System.ServiceProcess a las referencias del proyecto (está en la ficha .NET).

La forma más rápida:

return new ServiceController(SERVICE_NAME).Status == ServiceControllerStatus.Running; 

La manera más segura:

try 
{ 
    using(ServiceController sc = new ServiceController(SERVICE_NAME)) 
    { 
     return sc.Status == ServiceControllerStatus.Running; 
    } 
} 
catch(ArgumentException) { return false; } 
catch(Win32Exception) { return false; } 

La manera más detallada:

using System.ServiceProcess; 

// 

ServiceController sc; 
try 
{ 
    sc = new ServiceController(SERVICE_NAME); 
} 
catch(ArgumentException) 
{ 
    return "Invalid service name."; // Note that just because a name is valid does not mean the service exists. 
} 

using(sc) 
{ 
    ServiceControllerStatus status; 
    try 
    { 
     sc.Refresh(); // calling sc.Refresh() is unnecessary on the first use of `Status` but if you keep the ServiceController in-memory then be sure to call this if you're using it periodically. 
     status = sc.Status; 
    } 
    catch(Win32Exception ex) 
    { 
     // A Win32Exception will be raised if the service-name does not exist or the running process has insufficient permissions to query service status. 
     // See Win32 QueryServiceStatus()'s documentation. 
     return "Error: " + ex.Message; 
    } 

    switch(status) 
    { 
     case ServiceControllerStatus.Running: 
      return "Running"; 
     case ServiceControllerStatus.Stopped: 
      return "Stopped"; 
     case ServiceControllerStatus.Paused: 
      return "Paused"; 
     case ServiceControllerStatus.StopPending: 
      return "Stopping"; 
     case ServiceControllerStatus.StartPending: 
      return "Starting"; 
     default: 
      return "Status Changing"; 
    } 
} 

Editar: También hay un método sc.WaitforStatus() que toma un estado deseado y un tiempo de espera, nunca lo usó, pero puede adaptarse a sus necesidades.

Editar: Una vez que obtenga el estado, para obtener el estado nuevamente, primero deberá llamar al sc.Refresh().

Referencia: ServiceController objeto en .NET.

+9

ServiceController.GetServices() recupera una matriz que contiene todo el servicio instalado como objeto ServiceController. Esto puede ayudar mucho. – Larry

+0

Buena llamada, no sé si alguna vez lo he usado. Incluso si nunca lo usa, supongo que sería útil para la depuración si nada más – Carl

+8

sc.WaitforStatus() fuera exactamente lo que necesito. Thx – edosoft

18

Eche un vistazo al objeto ServiceController en .NET.

+2

Oooh ... incluso mejor que rodando el suyo a través de WMI. Eliminaré mi respuesta. – EBGreen

+3

@EBGreen - No sé, la ruta de WMI puede ser útil para otra persona en el futuro, hay más de una manera de despellejar a un gato, y todo eso .... – Carl

+1

Ya, pero realmente creo que ServiceController es mejor sobre todo, así que creo que lo dejaré eliminado. Nunca hubiera sugerido WMI si no hubiera despertado. :) – EBGreen

9

Aquí obtiene todos los servicios disponibles y su estado en su máquina local.

ServiceController[] services = ServiceController.GetServices(); 
foreach(ServiceController service in services) 
{ 
    Console.WriteLine(service.ServiceName+"=="+ service.Status); 
} 

Puede comparar su servicio con la propiedad service.name dentro del bucle y obtendrá el estado de su servicio. Para los detalles vaya con http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicecontroller.aspx también http://msdn.microsoft.com/en-us/library/microsoft.windows.design.servicemanager(v=vs.90).aspx

Cuestiones relacionadas