¿Cómo hacer un Servicio Windows en C#?

Los servicios Windows son programas que corren en background independiente del usuario que tenga sesiones activas en un server. Los usamos para múltiples tareas por ejemplo monitorear el estado de un Servicio Web.

Un cliente me pregunta cómo se puede hacer un servicio que monitoree un servicio Web y su tiempo de respuesta.

Fácil, hay que hacer un servicio Windows en C# 😉

Respuesta

Los pasos para construir un servicio Windows, utilizando C# son los siguientes:

  1. Crear un proyecto del tipo Windows Services.
  2. Implementar la lógica del Servicio.
  3. Agregar los parámetros de instalación del servicio.
  4. Crear un proyecto de Instalación.
  5. Instalar
  6. Extra, ¿cómo hacer Debug?

Paso 1: Crear un proyecto del tipo Windows Services.

Visual Studio tiene un tipo de proyecto especial para crear servicios Windows. En el cuadro de dialogo ‘New Project’ hay que seleccionar la opción ‘Windows Services’ como muestra la figura 1.

Figura 1.

Como resultado de esto se crea una clase llamada Service1 que contiene los siguientes métodos:

Service1(): constructor de la clase, aquí debemos incluir la configuración del Servicio.

OnStart(string[] args): Evento cuando el servicio se inicia. Esto ocurre cada vez que el servicio comienza a funcionar.

OnStop(): Evento cuando el servicio se detiene. Aquí se deben eliminar todos los recursos que el servicio utiliza.

 

Paso 2: Implementar la lógica del Servicio

Este servicio debe hacer lo siguiente:

  1. Consumir un Servicio Web cada cierto periodo de tiempo.
  2. Validar que el Servicio Web resposponda (no se caiga).
  3. Validar que el tiempo de respuesta en menor que cierto valor.
  4. Mantener en configuración la URL del Servicio Web, periodo de tiempo en que se repiten las llamadas y el tiempo de respuesta máximo.

Para consumir un Servicio Web utilizamos la funcionalidad de Visual Studio ‘Add Web Reference’ que se muestra en la figura 2. En este ejemplo utilizaré el servicio gratuito de  WebServiceX.

Figura 2.

Para realizar la tarea repetitiva de llamar al servicio Web cada cierto intervalo de tiempo utilizaremos un objeto del tipo System.Timers.Timer. Este objeto tiene la capacidad de levantar un evento cuando pasa cierto periodo de tiempo desde que se activa. En este caso la construcción del Timer se realzia en el método onStart del Servicio Windows, es decir cuando el servicio de levanta comienza a trabajar el Timer. Esto se muestra en el código 1.

 

 

   1: protected override void OnStart(string[] args)
   2: {
   3:     //Timer para el control del tiempo entre llamadas.
   4:     myTimer = new System.Timers.Timer();
   5:     //Intervalo de tiempo entre llamadas.
   6:     myTimer.Interval = 1500;
   7:     //Evento a ejecutar cuando se cumple el tiempo.
   8:     myTimer.Elapsed += new System.Timers.ElapsedEventHandler(myTimer_Elapsed);
   9:     //Habilitar el Timer.
  10:     myTimer.Enabled = true;
  11: }

Código 1.

En el evento myTimer_Elapsed se hace la llamada al Servicio Web. Pero, para evitar problemas de concurrencia se detiene el Timer antes de hacer la llamada y luego se vuelve a activar. Esto se muestra en el código 2.

 

 
   1: void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
   2: {
   3:     //Detiene el Timer
   4:     myTimer.Enabled = false;
   5:     //llama al Servicio Web
   6:     CallServicioWeb();
   7:     //habilita el Timer nuevamente.
   8:     myTimer.Enabled = true;
   9: }

Código 2.

Por último el método CallServicioWeb() hace la llamada y controla el tiempo de respuesta del Servicio. En el código 3 se puede ver la lógica de esto.

 

 
   1: void CallServicioWeb()
   2: {
   3:     //Proxy
   4:     SerivicioWeb.GeoIPService Proxy = new ServicioWindowsMonitor.SerivicioWeb.GeoIPService();
   5:     DateTime Tini;
   6:     TimeSpan Tdif;
   7:     try
   8:     {
   9:         //Tiempo de inicio de la llamada
  10:         Tini = DateTime.Now;
  11:         //llamada al servicio 
  12:         Proxy.GetGeoIP("200.10.12.126");
  13:         //Tiempo de respuesta
  14:         Tdif=Tini.Subtract(DateTime.Now);
  15:         if (Tdif.Seconds < -10)
  16:         {
  17:             Log("Servicio Lento: " + Tdif.Seconds.ToString()+ "[S]");
  18:         }
  19:     }
  20:     catch (Exception X)
  21:     {
  22:  
  23:         Log(X.Message);
  24:     }
  25: }

Código 3.

Paso 3: Agregar los parámetros de instalación del servicio.

Para que el servicio pueda ser controlado por el administrador de servicios de Windows debemos agregar dos componentes a nuestro Servicio Windows:

 

  • serviceProcessInstaller: en este componente se debe fijar el usuario con que se ejecuta el servicio. En este caso utilizamos la cuenta Local Service.
  • serviceInstaller: Este componente tiene la propiedad ServiceName, que define el nombre con que el Servicio aparece en la consola de Servicios. En este caso lo llamaremos ‘Monitor GeoIP’. Además este componente tiene la propiedad StartType que define si el servicio parte de manera automatica, manual o está desabilitado.

Para instalar estos componentes, en la vista de diseño del Servicio Windows usamos la opción ‘add Instaler’ del botón derecho. Esto se muestra en la figura 2.

Figura 2.

Paso 4: Crear un proyecto de Instalación

Para utilizar el servicio es necesario crear un instalador. Este proyecto instala el software del Servicio Windows en el disco, lo registra y agrega a la consola de servicios del sistema operativo.

Para crear un proyecto de instalación debemos utilizar el dialogo ‘New Project’ con la opción ‘Setup’ como muestra la figura 3.

Figura 3.

Una vez creado el proyecto debemos agregar a este proyecto de instalación en la carpeta ‘Application Folder’ el proyecto de salida. Este es nuestro proyecto de Servicio Windows. La figura 4 muestra cómo hacerlo usando el botón derecho.

Figura 4.

El siguiente paso es agregar este proyecto de salida a las acciones Install, Commit, RollBack y Uninstall. Para ello en la pestaña ‘Solution Explorer’ seleccionamos el botón ‘Custom Action Editor’. Luego en ese editor, agregamos el proyecto a todas las acciones, como lo muestra la figura 5.

Figura 5.

Paso 5: Instalar

Para instalar el Servicio Windows debemos hacer un Built del instalador y luego con el botón derecho sobre el proyecto de instalación ejecutar la instlación.

Una vez instalado, siguiendo los pasos del Wizard, podemos ver el servicio en la consola de servicios del sistema operativo. En la figura 6 se puede ver las propiedades del evento que ya está en la consola de servicios!!!!

Figura 6.

Paso 6: Bonus, Hacer Debug del Servicio.

Para poder hacer debug del servicio podemos hacer un Attach del proceso. Ojo, esto es posible poque lo compilamos en modo Debug. Para hacerlo vamos al menu Debug de Visual Studio, opción Attach. Cuando aparece el dialogo de procesos hay que buscar en la lista el nombe del servicio y apretar el botón attach. En ese momento Visual Studio entra en modo de debug. El dialogo de Attach se muestra en la figura 7.

Figura 7.

Una vez que se está en modo de debug, se puede poner un punto de interupción en el código y hacer debug a gusto.

Esto es lo básico para desarrollar un Servicio Windows, con esto pueden construir desde un sencillo servicio de monitoreo hasta complejos Host de Windows Comunication Foundation por ejemplo.

El código de ejemplo de esta demos pueden bajarlo desde Aquí

Salu2

23 comentarios en “¿Cómo hacer un Servicio Windows en C#?

  1. afogutu

    Maestroooooooooo!!!!! por gente como vos me hice programador.Me salvaste las papas del fuego que ni te imaginas…. Realmente muchas gracias.Omar.

    Responder
  2. Juan Pablo

    Estimado,
    Este tipo de mensajes son los que a uno le cargan las pilas y dan ánimo para seguir escribiendo por amor al arte.Muchas gracias.
    salu2

    Responder
  3. edgar

    Hola Muchas gracias por la explicacipon es muy buena y me saco de un apuro
     
    solo tengo una duda, segui todos tus pasos y al correr el instalador me pide un usuario y contraseña de inicio de secion del servicio y la verdad ya le puse el usuario con el que estoy logeado y no me daja instalarlo te agradeceria mucho tu ayuda
     
    gracias y Salu2

    Responder
  4. Myriam

    Hola muy buena explicación de la creación de un window services,
    yo tengo creado mi windows services, pero quisiera saber como se puede llamar a este servicio desde una aplicación web, para realizar el debug del mismo.
     
    Y también en este servicio necesito escribir un log en un archivo.
     
    Espero que puedas ayudarme.
     
     
    Gracias. 🙂

    Responder
  5. Juan Pablo

    Hola Ing. Edgar Cruz,
    El usuario que te pide el asistente es la identidad con que el servicio se ejecutará. Tienes que poner uno que tenga los permisos necesarios uno de sistema.
    Espero te sirva esta respuesta J

    Responder
  6. Juan Pablo

    Hola “Muñeca” (que buen Nick 😉 )
    No entiendo muy bien tu pregunta. Si lo que preguntas es como hacer conversar una aplicación WEB con el servicio Windows, debes utilizar WCF que es la solución de comunicaciones para cualquier necesidad de intercambiar información en Windows desde el Framework 3.0
    Si tu pregunta es como hacer debug, no necesitas hacer eso. Después de instalarlo utiliza VS para hacer Debug, tienes que usar la opción attach process…..
    Salu2

    Responder
  7. Mario Alejandro

    Puedes ser mas explicito en cuanto a la explicacion de como depurar el Servicio de Windows ??? he descargado tu codigo, he tratado de depurarlo pero no he podido…. puedes explicarme como le haces???
     
    saludos cordiales
     
    gbaltazar

    Responder
  8. Alvaro Hackmayer

    El codigo Fuente no esta disponible en el URL por favor mandarme el Url para poder descargarlo. Muy buena explicación Master espero poder analizarlo bien con el codigo fuente

    Responder
  9. Juan Pablo

    Hola…

    He implementado tu manual paso a paso y me va super bien.

    Estoy usando VS 2010, y no he podido correrlo pues me presenta varios errores..

    Es posible que postearas el código completo ?

    La verdad soy principiante con C#, ya corregí varios errores (6 de 10) pero no he podido con algunos de ellos.

    Felicitaciones y mil gracias por compartir tu conocimiento.

    Responder
  10. felipe

    Necesito colocar una aplicacion como servicio, osea que se levante cuando inicie el SO, me pregunto si este codigo sirve para ello, por ejemplo si hago lo mismo que esta aca y le adiciono esta linea System.Diagnostics.Process.Start(«C:\\PruebaRMI\\RMI.exe»); serviria o no sirve para levantar una aplicacion por que he buscado bastante y no he conseguido respuesta para windows 7, este mismo post esta en todo lado pero se me hace curioso que no hagan un ejemplo con lo que propongo, por que estoy seguro que todo el mundo anda buscando es colocar una aplicacion como servicio, ojala me colaboren que estoy muy urjido con el tema.

    Responder
  11. Andres.

    Hola, quisiera saber como poder agregar parámetros de configuración al servicio, es decir poder cambiar variables con el servicio ya instalado y no tener que modificar el código y compilar todas las veces… en mi caso lo que quiero cambiar es el tiempo del timer…

    Gracias y éxitos.

    Responder

Replica a Alvaro Hackmayer Cancelar la respuesta