E' un pò lunghetto questo post, comunque studiando per l'esame 70-320 oggi vedremo come varie cose sui Windows Services: come crearli, gli eventi etc.
COME SI CREA UN WINDOWS SERVICE
Si procede come un qualsiasi progetto .NET scegliendo come templete Windows Service. Viene anche in questo caso creato il nostro bel file AssemblyInfo.cs e Service.cs.Vediamo il codice generato in automatico per Service.cs:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
namespace WinService1
{
public class Service1 : System.ServiceProcess.ServiceBase
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public Service1()
{
// This call is required by the Windows.Forms Component Designer.
InitializeComponent();
// TODO: Add any initialization after the InitComponent call
}
// The main entry point for the process
static void Main()
{
System.ServiceProcess.ServiceBase[] ServicesToRun;
// More than one user Service may run within the same process. To add
// another service to this process, change the following line to
// create a second service object. For example,
//
ServicesToRun = new System.ServiceProcess.ServiceBase[] {new Service1(), new MySecondUserService()};
//
System.ServiceProcess.ServiceBase.Run(ServicesToRun);
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.ServiceName = "Service1";
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
/// <summary>
/// Set things in motion so your service can do its work.
/// </summary>
protected override void OnStart(string[] args)
{
// TODO: Add code here to start your service.
}
/// <summary>
/// Stop this service.
/// </summary>
protected override void OnStop()
{
// TODO: Add code here to perform any tear-down necessary to stop your service.
}
}
}
Supponiamo che il nome dato non ci piace, basterà rinominarlo con il tasto destro oppure dalla property File Name o da codice, nota che nell'esempio è riportato anche come aggiungere un altro service allo stesso processo
// The main entry point for the process
static void Main()
{
System.ServiceProcess.ServiceBase[] ServicesToRun;
//Cambiamo il nome del WindowsService
ServicesToRun=new System.ServiceProcess.ServiceBase[]
{new Service_CSharp()};
/*
Possiamo aggiungere più user Service allo stesso processo
mediante il seguente codice
ServicesToRun = new System.ServiceProcess.ServiceBase[] {new Service1(), new MySecondUserService()};
*/
System.ServiceProcess.ServiceBase.Run(ServicesToRun);
}
Vediamo qualche proprietà:
AutoLog: settata a false sarà utilizzato un custom event log
CanStop: specifica in che modo il nostro Service può stopparsi. Ad esempio se settato a true la SCM chiamerà il metodo OnStop quando una richiesta di stop è inviata al nostro service;
CanShutdown: specifica il tipo di notifica che il nostro Service riceve quando il sistema è in spegnimento. Ad esempio se settato a true la SCM informa il nostro Service che il sistema si sta spegnendo;
CanPauseAndContinue: specifica quando un utente può mettere in pausa o riavviare il nostro Service, l'override avverà sempre tramite la SCM;
CanHandlePowerEvent: questa è una proprietà che assume un valore boolean in base ai cambiamenti di "power" del nostro sistema.
Tutte queste proprietà come si modificano ? Basta fare click di destro sul pannello [Design] del nostro Service e visualizzare
Ora ok, abbiamo creato il nostro Windows Service ma non fa proprio nulla..... facciamogli fare qualche cosa , ad esempio creare/aprire un file di testo e scriverci delle informazioni , come al solito qualche riga di codice per capirci:
protected override void OnStop()
{
FileStream testo=new FileStream(@"C:\Documents and Settings\Rosalba\Desktop\MyPost\tex1service.txt",FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter testo2=new StreamWriter(testo);
testo2.WriteLine("Service_CSharp è in stop");
testo2.Flush();
testo2.Close();
}
GLI EVENTI
Come per l'esame 70-316 anche qui dobbiamo battagliare con gli eventi , togliamoci subito il dente:
Start: questo evento avviene quando avviamo il service da SCM. Possiamo specificare se il nostro service parta nella fase di boots o manualmente dall'utente (automatic, manual, disabled)
Stop: quando avviene questo evento la SCM "chekka" il valore della proprietà CanStop del nostro Service, se ad esempio la CanStop è settata a True la SCM passa il comando di Stop al Service ed effettua una call al metodo OnStop, nel caso la CanStop sia settata a False la SCM non passa il comando di Stop alla nostra Service
Pause: in questo caso la SCM "chekka" il valore della proprietà CanPauseAndContinue, il metodo interessato è OnPause. Una buona notizia: non dobbiamo preoccuparci della perdiata di varibili dichiarate perchè durante la pausa esser rimarrano in memoria anche durante la pausa.
Continue: ...credo sia chiaro cosa avviene
Alle volte vorremmo sapere cosa sta accadendo, ad esempio lo stato di un servizio, situazione di "poca" memoria etc per capire la causa di un errore ed il suo tipo utilizziamo gli event log. Il componente utilizzato è EventLog e possiamo "indagare" sia sul computer locale che su un computer remoto, grazie alla Server Explorer possiamo vedere a quali event log possiamo accedere, ossia una cosa tipo questa:
Ma quali e quanti event log abbiamo di default? Ne abbiamo tre:
system log: per i messaggi dei componenti del sistema
security log: messaggi riguardanti la security
application log:messaggi riguardandi gli eventi di applicazioni installate nel computer
Tanto per avere un'idea di cosa possiamo trovare, facciamo click di destro nella Server Explorer su Event Log e lanciamo la Event Viewer
Oltre i stystem log abbiamo i Custom Event Log. Per fa ciò dobbiamo utilizzare la classe EventLog ed il metodo CreateEventSource, inoltre occorre utilizzare il namespace System.Diagnostics. I passi da compiere:
- La proprietà AutoLog deve essere settata a False
- Aggiungere un istanza del componente EventLog dalla Toolbox
- Specificare un valore per la property Source e il nome del log file
Questo se preferiamo "giocare" con gli strumenti visuali, se preferiamo agire da codice invece:
private System.Diagnostics.EventLog eventLog1;
//
//
private void CreateEventLog()
{
//inizializziamo i componenti
eventLog1 = new System.Diagnostics.EventLog();
// creiamo un event log controllando se per caso fosse già esistente
if (!System.Diagnostics.EventLog.SourceExists("Mio Service")
{
System.Diagnostics.EventLog.CreateEventSource("Mio Service","Mio Log");
}
//specifichiamo allora quale event log utilizzare
eventLog1.Source="Mio Service";
}
Domani forse, anche se devo dire che mi sento già MOLTOOOOOOO MEGLIOOOOOOOOOO, sarà l'effetto dell'inesistente tutto intorno a me , concluderemo le puntate, almeno per ora, sui Windows Services
powered by IMHO 1.3