Come abbiamo visto nel precedente articolo, i Servizi di Windows consentono di lasciare un applicazione attiva anche se nessun utente ha effettuato il login sul computer, ma proprio per questa loro caratteristica non hanno (né possono avere) un interfaccia utente.
In questo articolo vedremo come realizzare un applicazione che funga da interfaccia di uno o più servizi: l’idea ispiratrice è il Microsoft Sql Server Service Manager, quella piccola applicazione ben conosciuta a chi ha installato Microsoft Sql Server 2000 e che risiede nella tray-bar per mostrarci lo stato dei servizi legati a Sql Server o permetterci di stopparli, riavviarli o metterli in pausa.
Al cuore di tutto c’è la classe ServiceController
che appartiene alla namespace System.ServiceProcesses. Occorre innanzitutto creare una variabile di questo tipo (per comodità riprendo i valori dell’articolo precedente):
Dim controller As New ServiceController controller.ServiceName = "tmFirst" controller.MachineName = "." ' indica il computer locale
A questo punto abbiamo a disposizione tutte le proprietà del servizio; ma non solo, abbiamo a disposizione anche i metodi Start
, Stop
, Pause
e Continue
che – rispettivamente – avviano, fermano, mettono in pausa e riavviano il servizio. Diventa perciò sufficiente agganciare una riga tipo
controller.Start
all’handler di un evento qualsiasi come un click di una voce di menu o di un pulsante.
Volendo perciò realizzare un applicazione che controlli un solo servizio, potremmo realizzare un applicazione residente nella tray-bar cui venga legato un menu con le classiche voci “Avvia”, “Ferma”, “Pausa”, “Continua”: al click su una di queste voci, viene creata una variabile ServiceController
cui vengono impostate le proprietà MachineName
e ServiceName
, infine invocato il metodo Start
o Stop
o Pause
o Continua
.
Private Sub mnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnStart.Click Dim controller As New ServiceController controller.MachineName = "." controller.ServiceName = "tmFirst" controller.Start End Sub Private Sub mnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnStop.Click Dim controller As New ServiceController controller.MachineName = "." controller.ServiceName = "tmFirst" If controller.CanStop controller.Stop End If End Sub Private Sub mnPause_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnPause.Click Dim controller As New ServiceController controller.MachineName = "." controller.ServiceName = "tmFirst" If controller.CanPauseAndContinue controller.Pause End If End Sub Private Sub mnContinue_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnContinue.Click Dim controller As New ServiceController controller.MachineName = "." controller.ServiceName = "tmFirst" If controller.CanPauseAndContinue controller.Continue End If End Sub
Come possiamo notare, è buona norma verificare che il servizio possa essere fermato prima di invocare il metodo Stop
; analogamente è bene verificare che il servizio possa essere messo in pausa e riavviato (ovviamente le due operazioni “vanno a braccetto”) prima di tentare di metterlo effettivamente in pausa o riavviarlo.
A questo punto potremmo raffinare ulteriormente il programma, abilitando i menu item a seconda dello stato attuale del servizio e delle varie probabilità CanStop
e CanPauseAndContinue
:
Private Sub EnableMenuItems() Dim controller As New ServiceController controller.MachineName = "." controller.ServiceName = "tmFirst" Select Case controller.Status Case ServiceControllerStatus.Paused, ServiceControllerStatus.PausePending mnStart.Enabled = False mnPause.Enabled = False mnStop.Enabled = False mnContinue.Enabled = True Case ServiceProcess.ServiceControllerStatus.Stopped, ServiceProcess.ServiceControllerStatus.StopPending mnStart.Enabled = True mnPause.Enabled = False mnStop.Enabled = False mnContinue.Enabled = False Case Else mnStart.Enabled = False mnPause.Enabled = controller.CanPauseAndContinue mnStop.Enabled = controller.CanStop mnContinue.Enabled = controller.CanPauseAndContinue End Select End Sub