Uno degli aspetti presi in considerazione dall'esame
70-536 riguarda la creazione e la lettura degli eventi di Windows, e la
creazione ex-novo di un nuovo log dove poter andare a gestire tutto quello che
ci serve. Quindi, abbandoniamo un attimo il nostro set di classi che abbiamo
visto fino a questo momento, e dedichiamo questo post alle classi del FX create
appositamente a questo scopo.
Ricordo innanzitutto, per dovere di cronaca, che è
possibile consultare l'EventLog di Windows, aprendo il Control Panel, andando
nel gruppo Administrative Tools e cliccando su Event Viewer. Di default, i
log disponibili sono 3: Application, Security e System. Oppure, meglio ancora,
attraverso il Server Explorer
incorporato nell'IDE di VS2005.
Ottenere l'evento degli EventLog disponibili
La classe EventLog del FX, contenuta nel
namespace System.Diagnostics, implementa
una serie di metodi statici che ci permettono una serie di informazioni.
Vediamoli nel dettaglio.
E' possibile ottenere l'elenco dei logs attualmente definiti nel sistema con
una semplice chiamata :
EventLog[] logs = EventLog.GetEventLogs();
La chiamata a GetEventLogs() ritorna un array di
oggetti EventLog su cui possiamo ciclare per ottenere i
friendly-name di ogni log. Ecco un esempio di function che ritorna un
string[]:
public static string[] GetAvaiableLogs()
{
EventLog[] logs = EventLog.GetEventLogs();
string[] returnValue = new string[logs.Length];
for (int i = 0; i < logs.Length; i++)
returnValue[i] = logs[i].LogDisplayName;
return (returnValue);
}
La classe EventLog espone diverse property: LogDisplayName (nome del log in chiaro), MachineName (nome del PC da cui si sta leggendo il log),
MaximumKilobytes e MinimumRetentionDays
.
Ottenere gli eventi in un EventLog
La property Entries dell'oggetto EventLog è la più
interessante, perchè contiene tutti gli eventi registrati in quel particolare
log: ogni evento viene gestito da una classe apposita del FX, la EventLogEntry. Nel codice qui sotto
ho scritto un metodo static che, dato un logName, ritorna una string[]
contenente tutti gli eventi corrispondenti:
public static string[] GetLogEntries(string logName)
{
if (EventLog.Exists(logName) == true)
{
EventLog[] myLogs = EventLog.GetEventLogs();
for (int i = 0; i < myLogs.Length; i++)
{
if (myLogs[i].Log == logName)
{
EventLog myLog = myLogs[i];
string[] returnValue = new string[myLog.Entries.Count];
for (i = 0; i < myLog.Entries.Count; i++)
returnValue[i] = myLog.Entries[i].Message;
return (returnValue);
}
}
}
return (null);
}
Il codice qui sopra è volutamente a scopo didattico. Ogni istanza di
EventLogEntry dispone di molte proprietà, che sono estremamente
familiari a chiunque abbia visto almeno una volta i dettagli di un evento
attraverso l'Event Viewer. Questa pagina su MSDN riassume tutti i membri di
EventLogEntry. I più interessanti sono Category, CategoryNumber, Message e Source.
Scrivere un evento in un
EventLog
Possiamo utilizzare il metodo WriteEntry della classe EventLog per
registrare un evento generato dalla nostra applicazione. Questo metodo dispone
di alcuni overload, che ci permettono di registrare un evento in modo più o meno
dettagliato, specificando parametri come Message, Category, EventID, etc.
Creare un eventlog dedicato alla nostra
applicazione
Nelle versioni di Windows 2000/XP, gli eventlog
disponibili di default sono tre: Application, Security e System. Attraverso il
FX, possiamo creare un nuovo source ed un nuovo eventlog tutto nostro, dove
potremo loggare gli eventi specifici della nostra applicazione .NET. Per far
questo, basta una chiamata al metodo CreateEventSource. Dal momento che
occorre avere i diritti amministrativi per poter fare un'operazione di questo
tipo, è buona norma creare il nuovo eventlog durante il setup della nostra
applicazione, facendo uso della classe EventLogInstaller . Da
notare che tutte le classi viste sinora possono gestire sia il sistema locale, sia
un sistema remoto, specificando la machinename su cui vogliamo lavorare.
Questa cosa non è vera per l'EventLogInstaller, che invece può creare nuovi
eventlog solo sul sistema locale.