Servicios Windows en .NET (3ª parte) Julio 14, 2008
Posted by ravelus in Informática.add a comment
Depuración
Una vez hemos logrado instalar correctamente el servicio y lo hemos conseguido iniciar, podemos depurarlo durante su funcionamiento con Visual Studio, lo cual está muy bien. Para ello, lo primero que tenemos que hacer es asociar el Debugger de VisualStudio con el proceso que deseamos depurar o tracear:
Asociar un Servicio Windows en ejecución
Simplemente señalar que, como ya hemos dicho, el servicio debe estar ejecutándose en estos momentos.
- Cargue el proyecto del Servicio en Visual Studio.
- Haga clic en el menú Debug (*)
- Haga clic en la opción Processes (*)
- Asegúrese de que la opción Mostrar todos los procesos está seleccionada.
- Haga clic sobre el proceso que desea asociar, en la lista de Procesos Disponibles.
- Haga clic sobre el botón Asociar.
- Haga clic sobre OK, y después sobre Cerrar.
- Ahora puede establecer puntos de interrupción donde desee, y esperar que la ejecución del servicio llegue a tales puntos.
(*)NOTA: En la versión en Castellano de VisualStudio, esta opción se encuentra en Herramientas->Asociar al Proceso…
Esto es todo. Espero que les haya servido de algo y que a más de uno le haya solucionado la papeleta. Agradecería mucho sus comentarios y opiniones al respecto; si les he ayudado en algo y, por supuesto, si tienen algún problema también pueden dejar un comentario y yo personalmente, si soy capaz, trataré de ayudarles.
Apéndice: Manejo de rutas de directorios.
MUY IMPORTANTE: Por alguna razón que se escapa a mi raciocinio, al convertir un programa de consola corriente y moliente a Servicio Windows la ruta de ficheros raíz (el Path) desde la que se ubica el programa (normalmente el directorio \bin de la aplicación correspondiente) se trastoca y se cambia a C:\Windows\. Esto no supone ningún problema salvo si tenemos que indicar alguna ruta para escribir o leer de un fichero, por ejemplo, lo cual supone un gran problema porque es un dato que podemos leer pero no modificar. Por mucho que os molestéis en ir al Administrador de Servicios y ver las Propiedades del Servicio instalado, aunque en la ruta sea correcta y apunte al directorio de la aplicación, en realidad al ejecutar irá al directorio Windows.
¿Cómo solventar el problema? Bueno, yo lo hice introduciendo esta ruta en el registro de Windows, lo cual no es mala idea porque permite configurar vuestra aplicación de forma personalizada en la máquina cliente, en el directorio que queráis, lo cual desacopla bastante la instalación del código de la propia aplicación. No me parece correcto, por tanto, introducir rutas fijas, absolutas, en el código, porque si cambiamos de máquina es posible que la estructura de ficheros o el volumen cambie, lo cual nos obliga a modificar el código y recompilar, lo cual es inadmisible. De otro modo solamente tendremos que modificar una clave de registro, y si a este servicio le creamos un instalador MSI donde el usuario indique esta ruta la solución será muchísimo mejor y más elegante.
Por si no sabéis cómo se lee del Registro de Windows, podéis buscar en Internet, pero para que veáis lo bueno que soy, aquí os indico un ejemplo, para los más vagos:
public static string leerRutaConfigRegistro()
{
//Lee del registro de windows la ruta hacia los archivos de configuración
string rutaConfiguracion = "";
//accedemos al registro
RegistryKey mKey = Registry.LocalMachine.OpenSubKey(@"Software\<miEmpresa>\Paths\", true);
//si existe la clave, la traemos
if (mKey != null)
{
try
{
rutaConfiguracion = mKey.GetValue("RutaConfig").ToString();
}
catch (Exception eo)
{
/* Devolvemos una cadena vacía; el invocador de esta llamada va a dar un error y se encargará
* de hacer lo que tenga que hacer, como de lanzar una excepción, por ejemplo
* mediante 'throw'
*/
Log.Write("No se pudo acceder a la ruta de Configuración. " + eo.Message, true);
return "";
}
}
mKey.Close();
return rutaConfiguracion;
}
Creo que está bastante claro y documentado el código. Si no, dénle un par de vueltas, no lo voy a hacer yo todo…
————————————————————————————————————————————————————————–
Fuente original en inglés (aunque gran parte del artículo son notas propias):
http://www.developer.com/net/csharp/article.php/10918_2173801_1
Donde encontraréis un ejemplo incluso.
Servicios Windows en .NET (2ª parte) Julio 7, 2008
Posted by ravelus in Informática.add a comment
Instalación
Una vez escrito y depurado nuestro código (si lo creamos inicialmente como Aplicación de Consola, lo cual recomiendo, y luego añadirle la clase Service correspondiente con los métodos OnStart, OnStop, etc, ya explicados…) procedemos a su instalación.
Los servicios windows son diferentes a otras aplicaciones basadas en Windows al uso, como ya hemos dicho al comienzo. No es posible ejecutar un servicio simplemente ejecutando el archivo .exe. El servicio debe ser instalado utilizando una aplicación del Framework .NET denominada InstallUtil, la cual utiliza proyectos de instalación de Microsoft Installer (MSI).
Añadir un instalador a nuestro servicio
Tener creado nuestro servicio, y compilado en Debug o en Releas no será suficiente para que InstallUtil pueda instalar el servicio. Esto es importante porque aquí perdí bastante tiempo intentando hacerle entrar en razones a la aplicación InstallUtil. Para instalar correctamente, es necesario crear un instalador al servicio para que InstallUtil conozca los parámetros de insatalción que hay que aplicar al servicio a instalar.
- Cambie a la vista de diseño del servicio.
- Haga clic derecho y seleccione la opción Añadir Instalador.
- Cambie a la vista de diseño del ProjectInstaller que se ha añadido.
- Establezca las propiedades del componente serviceInstaller1.
1. ServiceName= <el_nombre_de_mi_servicio>
2. StartType=<Automatic, Manual….> - Establezca las propiedades del componente serviceProcessInstaller1
1. Account = LocalSystem (esto es muy importante, o el servicio no será capaz de iniciarse correctamente) - Compile la solución.
NOTA: Juege con el resto de propiedades de los componentes creados con el instalador. Investigue las opciones que le permite controlar. Es interesante, por ejemplo, asignar al servicio una descripción lo más explicativa posible de las funciones de su servicio. Esta descripción será visualizada posteriormente en el Administrador de Servicios.
Instalar el servicio con InstallUtil
Ahora que el servicio ha sido construido correctamente, es el momento de instalarlo para utilizarlo:
Instalación desde shell de comandos de .NET
En primer lugar, abriremos una ventana de comandos de .NET. (Inicio->Programas->Microsoft .NET Framework SDK 2.0->Símbolo del sistema de SDK).
Cambiamos el directorio a aquel donde esté ubicado MiServicio.exe. Y ejecutaremos:
InstallUtil MiServicio.exe
Leer la información que aparece. Si todo ha ido bien, el servicio se habrá dado de alta en el servicio. Automáticamente se habrá establecido que se inicie en modo automático a partir de ahora en los siguientes inicios de la máquina.
Pero habrá que iniciarlo por primera vez. Para ello, abrir las Herramientas administrativas y visualizar los Servicios (Panel de Control->Herramientas Administrativas->Servicios). A continuación, poner en funcionamiento el servicio, . Por último, verificar los logs para comprobar que todo ha ido correctamente.
Instalación desde shell de comandos de Windows
Aunque recomiendo encarecidamente la primera opción, si no encontramos el shell de comandos de .NET, podremos instalar la aplicación desde la ventana de comandos de Windows, ejecutando Inicio->Ejecutar y escribir “cmd”. Pulsar Intro.
Cambiar al directorio C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727, y ejecutar:
Installutil c:\<ruta>\MiServicio.exe
donde <ruta> es la ruta del ensamblado MiServicio.exe.
Bien. Una vez instalado podemos ir a las herramientas administrativas del sistema y ver el listado de Servicios. Iniciar el servicio cuyo nombre será MiServicio.exe, y en sus propiedades, establecer que se inicie automáticamente al arrancar Windows (pestaña “General“). También sería interesante marcar, en la solapa “Recuperar“, “Reiniciar el servicio” en todos los fallos que pudieran ocurrir.
Desinstalación
Para desinstalar el servicio del sistema, abriremos un shell de .NET o una ventana de comandos de Windows, y realizando las mismas operaciones para acceder al comando InstallUtil como hicimos antes, ejecutaremos:
InstallUtil /u MiServicio.exe
Como se ve, es el mismo comando de antes pero con la opción /u.
Esto es todo. Con esto debería ser suficiente.
Servicios Windows en .NET (1ª parte) Julio 1, 2008
Posted by ravelus in Informática.add a comment
Hace no mucho me las tuve que ver y desear para migrar un servicio en C++ (infumable) a .NET, escrito en C#, y tuve bastantes problemas para conseguirlo instalar y hacerlo funcionar. Por ello, por la cantidad de horas que perdí buscando información y probando cosas, he decidido aportar mi granito de arena redactando un artículo que, si alguien tiene la suerte de dar con él, espero que le resuelva todos sus problemas de forma rápida. Concretamente traduzco de forma muy libre y amplío con bastantes notas de mi cosecha un artículo que encontré en Internet. Al final indicaré la fuente, como debe ser, para que encontréis toda la información necesaria.
Explicaré en los apartados siguientes cómo crear, instalar y depurar un servicio windows, aunque, personalmente creo que la mejor forma de depurar un Servicio Windows es comenzar creando un proyecto de Consola para Windows y después añadirle lo necesario para convertirlo en Servicio, es decir, una clase Service con los métodos OnStart() y OnStop() y lo necesario para lanzar dicho servicio: ServiceBase, ServiceToRun, etc.
Qué es un Servicio Windows
No me centraré en el potencial de un Servicio Windows. Remito al lector a buscar información, pero como ejemplos, saber que podemos interactuar con una base de datos, leer y escribir en el registro Windows, crear y eliminar archivos (lo típico, nada nuevo), además de manejar los Logs de los Servicios Windows y las Colas Windows para enviar y recibir mensajes. No entraré en detalle con estos puntos y remito de nuevo al lector a que busque en la Red.
Un servicio Windows es una aplicación que se ejecuta indefinidamente sin participación del usuario en background, es decir, sin que el usuario tenga constancia de su funcionamiento mediante una ventana de cualquier tipo, puesto que no interactúan con el usuario. Para ver estos servicios puede abrir el Administrador de Tareas y, en la pestaña Procesos se listarán todos estos servicios que están funcionando. Estos servicios pueden ser gestionados, además, mediante el Administrador de Servicios, dentro del panel de contol y luego en Herramientas Administrativas, y gestionar ciertas cuestiones de su funcionamiento, como nombre, qué hacer cuando el servicio falla, cómo arrancarlo, etc.
Estos servicios fueron introducidos con Windows NT. No existen en Windows 9x ni Windows Me.
Lo que realizan estos programas son ciertas tareas de gestión, estar alerta ante ciertos eventos, abrir ciertos puertos o servicios, informar a las capas superiores de ciertos eventos que sucedan durante el funcionamiento de la máquina, etc. Ejemplos: las dichosas actualizaciones automáticas están alerta de que Microsoft envíe mensajes de actualización para pedir a los usuarios que existen actualizaciones disponibles y que deberían hacerlo. SQLServer, Microsoft Exchange… son otros ejemplos de servicios, que nos permiten acceder al SGBD o recibir correos y notificarnos, respectivamente.
Creación de un Servicio Windows
Para ver el ejemplo que la fuente explica aquí, les remito al final del artículo para ver el artículo original en inglés, donde se explica un ejemplo de cómo crear un servicio.
En Visual Studio .NET es bastante sencillo crear un Servicio Windows. Simplemente hay que seguir los siguientes pasos:
- Comience un nuevo proyecto
- Seleccione Servicio de Windows de la lista de plantillas disponibles.
- El diseñador se abrirá en modo diseño.
- Arrastre un objeto Timer desde la solapa de Componentes en la Caja de Herramientas al área de diseño (Aviso: asegúrese de que usa el Timer de la solapa Componentes y no el que viene con Windows Forms).
- Acceda a las propiedades del objeto Timer y establezca la propiedad Enabled a falso y la propiedad intervalo a 30000 milisegundos.
- Cambie a la vista de código (pulsando F7) para añadir la funcionalidad al servicio.
Código del Servicio
En el código de la clase notará que el servicio Windows extiende la clase System.ServiceProcess.Service (de la cual es hija).
Todos los servicios Windows creados con .NET deben extender esta clase. Es obligatorio que su servicio sobreeescriba los siguientes métodos, los cuales son incluidos por Visual Studio por defecto.
- Dispose – limpia todos lso recursos
- OnStart – controla el inicio del servicio
- OnStop – controla la fase de parada del servicio
NOTA: Hay otros, como OnPause. Para más información, busque en la Red
.
CONTINUARÁ…

