2010-09-12 28 views
27

Como en el siguiente enlace, uno puede detener, iniciar y "detener, luego iniciar" un servicio utilizando el código C#.¿Cómo enviar un comando personalizado a un servicio Windows .NET desde el código .NET?

http://www.csharp-examples.net/restart-windows-service/

me han preparado un servicio de .NET que no implementar OnStart y OnStop. Sin embargo, tengo que implementar una funcionalidad de "reinicio inteligente" que es más importante que simplemente detener y luego iniciar. Necesito mantener el tiempo de inactividad en solo unos segundos si eso (pero Stop + Start puede tomar minutos en este caso cuando se hace limpiamente, y debo hacerlo limpiamente), y tener algunas partes del sistema disponibles mientras otras se reinician/actualizan .

Resumen a largo plazo: antes de saltar a la implementación de esta funcionalidad OnSmartRestart, quiero asegurarme de que hay una forma bastante sencilla de invocar esta llamada desde otra aplicación C#.

Esta característica es importante, pero peligrosa. Quiero que quede bastante oculto, algo seguro, también sencillo, y asegúrese de que esto tenga un efecto insignificante en el rendimiento de mi servicio de Windows mientras realiza sus tareas habituales y no reinicia.

Si tengo que sondear algún archivo o abrir un puerto y gastar demasiada CPU en hacer eso, no sería una buena solución. También quiero mantener esto TAN SENCILLO COMO SEA POSIBLE (lo siento por la repetición).

Respuesta

48

Puede enviar "comandos" de un servicio utilizando ServiceController.ExecuteCommand:

const int SmartRestart = 222; 

var service = new System.ServiceProcess.ServiceController("MyService"); 
service.ExecuteCommand(SmartRestart); 
service.WaitForStatus(ServiceControllerStatus.Running, timeout); 

Usted tendrá que añadir una referencia al ensamblado System.ServiceProcess.dll.

El servicio puede reaccionar a la orden anulando ServiceBase.OnCustomCommand:

protected override void OnCustomCommand(int command) 
{ 
    if (command == SmartRestart) 
    { 
     // ... 
    } 
} 
+15

Información adicional: el comando DOS SC.exe también puede enviar estos comandos, permisos de seguridad que permiten ... p. Ej. 'SC CONTROL YOURSERVICENAME 200' – Adrian

+0

Adrian, ¿cómo se llama normalmente usando el comando, si su método es una alternativa? ¿Es "200" en su comando análogo a 222 en el código fuente anterior? – MacGyver

+1

Tenga en cuenta que esto requiere permisos especiales en un entorno de Servidor típico donde su aplicación/sitio .Net se está ejecutando por sí mismo, usuarios de permisos limitados. Puede resolverlo dando permiso a ese usuario para enviar comandos personalizados a este servicio utilizando este método: http://i.imgur.com/tql3pUA.png http://superuser.com/a/315709/101698 –

12

los medios habituales de comunicación con los procesos externos en Windows son:

  1. Las canalizaciones con nombre
  2. sockets
  3. COM GetObject para obtener una referencia a un objeto y luego llamar a sus métodos sobre la interfaz expuesta.

Los primeros dos han sido expuestos como WCF, así que ese es el camino a seguir. El tercero no parece relevante para su situación y es antiguo.

Si necesita ejecutar sus comandos desde la misma máquina, puede usar conductos con nombre pero el endurecimiento ha hecho que sea muy difícil y problemático. De lo contrario, utilice el enlace TCP de WCF.

+2

Esta respuesta es superior (y obligatoria) si planea enviar parámetros. –

+0

En general, esta respuesta parece superior para cualquier caso en el que desee tomar comandos de una aplicación "userland", que parece ser el caso para el OP. El uso de un servicio WCF no requiere mucking con permisos, que pueden ser más seguros y más convenientes. También hay un [artículo de MSDN sobre servicios de alojamiento WCF de un servicio de Windows] (https://msdn.microsoft.com/en-us/library/ms733069). – ZX9

Cuestiones relacionadas