|
La siguiente porción apertura un bloque try - catch y en este se verifica la existencia del archivo que manipulará el servicio, de no hallarse se creará en la ubicación especificada por PathFile, caso contrario se abre para que esté listo para escritura. A continuación se marca el inicio de un trabajo de escritura y se inicia el hilo o thread que se ha declarado. De ocurrir alguna excepción, se la captura y se registra la descripción de la misma en el log usado por el servicio usando el procedimiento LogEvent
Pasamos a ver ahora el procedimiento donde se da la tarea principal del servicio. Esta consiste simplemente en escribir líneas en el archivo de texto que manipula, la frecuencia está determinada por el tiempo de inactividad configurado para el hilo o thread declarado y especificado en la variable timeSleep.
Private Sub Writing()
Dim Dia As String
Dim Hora As String
Dim ci As CultureInfo = New CultureInfo("es-PE")
Dim count As Long = 0
While True
Try
'Los formatos de fecha y hora dependen de la cultura configurada en
el equipo
'Aplica formato dd/MM/yyyy para fecha
Dia = DateTime.Today.ToString("dd/MM/yyyy")
'Aplica formato largo para tiempo
Hora = DateTime.Now.ToString("T", ci)
count = count + 1
objWriter.WriteLine(CStr(count).PadLeft(10, "0") & " " & Dia & " "
& Hora & " " & CStr(count).PadLeft(10, "0") & " " & Dia & " " & Hora)
Hilo.Sleep(Me.timeSleep)
Catch ex As Exception
LogEvent(ex.Message)
End Try
End While
End Sub
|
En el ejemplo el tiempo de inactividad se ha establecido a 3000 milisegundos. Es decir se escribe una línea en el archivo de texto y se mantiene dormido al thread, por así decirlo, por ese periodo de tiempo, después del cual reanuda su ejecución y así sucesivamente hasta que se decida detener el servicio. En caso de ocurrir alguna excepción, esta se captura y se registra el detalle en el log del servicio.
A continuación se revisarán los procedimientos para la pausa, reinicio y detención de la tarea llevada a cabo por el servicio.
Al producirse el evento de pausa se registra una línea indicando que la tarea ha sido pausada y la fecha y hora en que se realizó esta acción. Para pausar la ejecución del thread se invoca al método Suspend de la variable que representa nuestro hilo de ejecución.
Protected Overrides Sub OnPause()
objWriter.WriteLine("Pausa del trabajo: " & Now())
Hilo.Suspend()
End Sub
|
Al reiniciar el servicio se ejecutará el código del procedimiento OnContinue, aquí se escribirá una línea de texto indicando la fecha y hora en que se reinició la tarea. Para reiniciar la ejecución de nuestro hilo o thread se invoca al método Resume.
Protected Overrides Sub OnContinue()
objWriter.WriteLine("Reinicio del trabajo: " & Now())
Hilo.Resume()
End Sub
|
Cuando se mande a detener el servicio, se ejecutará el código del procedimiento OnStop. En este procedimiento se escribe una línea de texto indicando la finalización de la tarea con la fecha y hora en que se detuvo el servicio. Al detener el servicio se invoca al método Abort que detendrá la ejecución de nuestro hilo o therad previa verificación de su existencia o ejecución.
Protected Overrides Sub OnStop()
Try
objWriter.WriteLine("Fin del trabajo de escritura: " & Now().ToString)
objWriter.Close()
' Matar el hilo
If Not (Hilo Is Nothing) And Hilo.IsAlive Then
Hilo.Abort()
End If
Catch exc As Exception
LogEvent(exc.Message)
End Try
End Sub
|
Por ultimo mostramos el procedimiento que nos ayuda a registrar los sucesos o excepciones que se pudieron presentar en cualquiera de los procedimientos descritos.
Public Sub LogEvent(ByVal Mensaje As String)
Try
Me.AutoLog = False
If Not EventLog.SourceExists("Writer Service Log") Then
EventLog.CreateEventSource("Writer Service Log", "MyLogFile")
End If
log.Source = "Writer Service Log"
log.WriteEntry(Mensaje)
Catch e As Exception
End Try
End Sub
|
Habiendo agregado la funcionalidad necesaria a los procedimientos principales de nuestro servicio, queda por añadir las clases de instalación para poder ponerlo en ejecución.
Para ello se selecciona el archivo de nuestro servicio y se va a la vista de diseño. Una vez allí se despliega el menú contextual y se selecciona Add Installer.

Figura 5. Añadiendo componentes de instalación para el servicio.
Una nueva clase llamada ProjectInstaller y dos componentes de instalación, ServiceProcessInstaller y ServiceInstaller se agregaron al proyecto, como se muestra en la figura 6.

Figura 6. Configurando los componentes de instalación para el servicio
Ahora hay que hacer clic sobre el componente ServiceInstaller y verificar que el valor de la propiedad ServiceName sea el mismo que el de la propiedad ServiceName del archivo de clase del servicio.
Para establecer el modo de inicio del servicio, clic sobre el componente ServiceInstaller y establecer StartType a Manual para nuestro caso.
Sobre el componente ServiceProcessInstaller hacer clic y establecer para nuestro caso la propiedad Account a LocalSystem
Generemos el ejecutable para nuestro proyecto y así estaremos listos para instalarlo. Desde la línea de comandos de Visual Studio, como se muestra en la figura 7, tendremos que acceder al directorio bin del proyecto y usar el comando installutil seguido del nombre del servicio, en nuestro caso será:
Para instalar el servicio: Installutil WriterSample.exe
Para desintalar el servicio: Installutil /u WriterSample.exe

Figura 7. Instalando el servicio
De esta manera el servicio podrá ser visto desde la consola de servicios del sistema operativo y podremos controlarlo, pudiendo iniciarlo, pausarlo, reiniciarlo y detenerlo; pudiendo ver como manipula el archivo de texto.
Conclusiones
Los Servicios Windows son de gran utilidad si se desea automatizar la ejecución de tareas de larga duración con una carga de trabajo considerable evitando que interfieran al nivel de interfaz de usuario, haciendo su trabajo en background y en forma transparente al usuario.
El ejemplo expuesto muestra una forma sencilla de cómo un Servicio Windows puede realizar su trabajo. Queda a criterio del desarrollador implementar formas mas sofisticadas para la ejecución de tareas dentro de un Servicio Windows. En este sentido se pueden usar temporizadores para realizar tareas de forma periódica y configurar su intervalo de ejecución, hacer verificaciones contra base de datos, notificaciones por correo electrónico, manipulación de archivos, etc.
Referencias
Windows Services Applications -
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon/html/ vboricreatingconfiguringwindowsserviceapplications.asp
Creando Servicios Windows -
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon/html/ vboricreatingconfiguringwindowsserviceapplications.asp
|