¿Cómo correr programas en segundo plano como servicios de windows?

Windows Service Add comments

Recientemente me encargaron una aplicación que leyera varios feeds y los almacenara en una base de datos sin que tuviera que intervenir un usuario. Y se me ocurrió que crear un servicio de windows sería la mejor forma de hacerlo.

Para ponerlo en palabras sencillas, un servicio windows es un ejecutable que -en segundo plano- realiza tareas especificas como monitorear cambios en archivos del sistema o en perifericos (USB, disco duro externo,…), o cualquier cosa que necesitemos hacer automáticamente, por ejemplo recordatorios o enviar correos. Su característica más interesante es que un servicio no requiere intervención de un usuario, funcionan al fondo. Por lo mismo, en la mayoría de los casos no son visibles en el entorno UI del usuario (aunque no es el caso, por ejemplo, de la consola SQL server Service Manager de MS SQL Server). La no-visibilidad y la autonomía de esos procesos, ocasionó, en el mundo UNIX®, su asosiación con la palabra “daemon”. Aunque se parecen, las palabras “daemon” y “demonio” no significan lo mismo. Evi Nemeth, co-autora del libro “UNIX System Administration HandBook“, indica lo siguiente:

Many people equate the word “daemon”‘ with the word “demon”, implying some kind of Satanic connection between UNIX and the underworld. This is an egregious misunderstanding. “Daemon” is actually a much older form of  “demon”; daemons have no particular bias towards good or evil, but rather serve to help define a person’s character or personality. The ancient Greeks’ concept of a “personal daemon” was similar to the modern concept of a “guardian angel” — “eudaemonia” is the state of being helped or protected by a kindly spirit. As a rule, UNIX systems seem to be infested with both daemons and demons.

El servicio que desarrolle se encarga, mediante un uso básico de threads, de hacer peticiones HTTP a una serie de ligas RSS. El resultado de las peticiones se procesan y almacenan en una base de datos. Visual Studio 2005 y 2008 ofrecen todo lo necesario para desarrollar un servicio de tipo “Hello world” en unos instantes. Les aconsejo desarrollar primero una aplicación de consola y luego pasar su código en un servicio para evitar perder tiempo en instalar y desinstalar el servicio durante la fase de debugeo. Cuando tiene listo su ejecutable, nada más le falta instalarlo mediante la herramienta installutil.exe que se encuentra en:

%SystemRoot%\Microsoft.NET\Framework\v2.0.50727

Para installar el servicio:

installutil "C:\serviciosWindows\miAssembly.exe"

Para installar el servicio y cambiar la ruta del log de instalación:

installutil
/LogFile="C:\serviciosWindows\log\instalUtil.installLog"
"C:\serviciosWindows\miAssembly.exe"

Para desinstallar el servicio:

installutil /u "C:\serviciosWindows\miAssembly.exe"

No tuve ningún problema para instalar mi servicio en XP Pro. Sin embargo, cuando lo intente hacer en una máquina Vista me encontre con unos problemas de seguridad. A la hora de arrancar, el servicio lanzaba un error en el CLR Debugger:

No se controló System.Security.SecurityException
Message="No se encontró el origen, pero no se pudo buscar en algunos o
todos los registros de eventos. Registros inaccesibles: Security."
Source="System" StackTrace: en System.Diagnostics.EventLog.FindSourceRegistration(String source,
String machineName, Boolean readOnly) en System.Diagnostics.EventLog.SourceExists(String source, String machineName) en System.Diagnostics.EventLog.SourceExists(String source) en Lab.MiServicio..ctor() en Lab.Program.Main()

Y del lado de la consola de los servicios (services.msc):

Windows no pudo inicar el servicio "" en Equipo local. Error 1053: El servicio no respondió a tiempo a la solicitud de inicio o de control.

Cuando un servicio arranca, intenta registrarse en el visor de eventos. Si no tiene los permisos necesarios, se termina inmediatamente. Para evitar esta restricción, se tiene que abrir el cmd con los derechos de administrador y luego ejecutar el commando de instalación. Además de ser una herramienta muy poderesa, los servicios generalmente obligan el programador a trabajar con threads. Lo cual implica unos dolores de cabeza pero nuevas ideas para solucionar problemas de computación.

Ligas de interés:

http://www.freebsd.org/copyright/daemon.html
http://es.wikipedia.org/wiki/Daemon

7 Responses to “¿Cómo correr programas en segundo plano como servicios de windows?”

  1. Evg Says:

    Compañero Jerome, ¡es usted un genio!

  2. Vida Says:

    éjele, sus links no son links :D

  3. admin Says:

    @Vida: Ya están los links :)

  4. Vida Says:

    @admin: eres jdecuyper?

  5. admin Says:

    @Vida: admin = jdecuyper :)

  6. noe Says:

    Como paso una aplicacion de consola a servicio windows? se puede hacer lo mismo con una aplicacion WinForm?

  7. admin Says:

    @noe: No existe una forma sencilla de transformar una aplicación de consola o WinForm en un servicio Windows. Aunque ahora con el framewok .NET todo está simplificado. Si necesitas correr tu programa tanto como servicio o consola, te aconsejo desarrollar una liberería con las clases y el funcionamiento que necesitas. Esta librería estaría independiente del ambiente en dónde corre, la podrías usar para un proyecto tanto para un servicio windows.
    De hecho muchas veces es mucho más facil debugear un servicio desde una consola que desde los logs de windows.

Leave a Reply

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in