Della classe Installer abbiamo già parlato molto tempo fa. Era il 27 settembre, e mi
stavo preparando per l'esame 70-316. Quel giorno abbiamo visto come aggiungere
alla nostra soluzione un nuovo progetto Class Library,
come implementare una classe custom che eredita da Installer.
Tale classe viene consumata da Windows Installer durante il setup della nostra
applicazione. Possiamo in pratica fare l'overloading degli eventi che accadono
durante il processo di installazione, quindi gestire manualmente la Commit,
provocare il Rollback, e via dicendo. Ma non solo: ci eravamo spinti un po' più
in là. Avevamo aggiunto Custom Dialog, richiedendo alcune informazioni
all'utente, come il suo indirizzo e-mail, oppure altre informazioni più semplici
tramite CheckButton o RadioButton. Se volete implementare qualcosa di simile,
consiglio caldamente di vedere il mio vecchio post, perchè io stesso ho avuto
qualche difficoltà che sono riuscito a risolvere consultando me stesso
indietro nel tempo. Questo è un paradosso temporale, ma lascio che siano Doc e
Marty a tirarmi fuori dai guai senza provocare qualche casino nello
spazio-tempo.
In questo post, darò per assodate un sacco di cose, quelle cioè descritte nel
post a cui mi riferivo più sopra. In questi giorni ho ripreso in mano
l'argomento, perchè ho voluto preparare un setup un po' particolare al mio
software di fatturazione. Quindi, mi sono complicato la vita, giusto per
approfondire la questione. Nulla di trascendentale, sia chiaro, ma è comunque
qualcosa di interessante. Vediamo perchè.
La classe InstallContext
Dal punto di vista prettamente
teorico, la classe InstallContext ci fornisce
informazioni sull'Installer corrente. Essa si trova nel namespace System.Configuration.Install. Involontariamente, ne abbiamo già
parlato. Quando ad esempio overloadiamo l'evento
Commit, possiamo scrivere quanto segue:
public override void Commit(System.Collections.IDictionary savedState)
{
base.Commit(savedState);
InstallContext ctx = this.Context;
string db = ctx.Parameters["DB"];
string cognomeNome = ctx.Parameters["COGNOME_NOME"];
string provincia = ctx.Parameters["PROVINCIA"];
string email = ctx.Parameters["EMAIL"];
}
Nel codice qui sopra, non facciamo altro che usare un'istanza di
InstallContext, che ci permette di reperire le informazioni inserite dall'utente
nella prima fase del setup. La proprietà Parameters serve proprio a
questo: nell'esempio qui sopra, DB è un CheckButton (che può essere recuperato
anche dal metodo IsParameterTrue), mentre le
altre COGNOME_NOME, PROVINCIA ed EMAIL sono normali TextBox che l'utente ha
inputato. L'istanza è ritornata dalla property Context della classe
Installer, che rappresenta per
l'appunto l'engine di Windows Installer che sta girando in questo momento.
Interessante l'uso del metodo LogMessage che ci permette di
scrivere sul file di log dedicato per questo setup, utile magari per capire cosa
ha inserito l'utente e come si è comportato di conseguenza l'installer.
Altre classi che riguardano il setup
Il namespace
System.Configuration.Install contiene altre classi, alcune interessanti, altre
un po' meno. La classe ManagedInstaller, per esempio, non deve essere usata
direttamente nei nostri Installer: fa parte integrante dell'engine del FX, e
quindi viene utilizzata solo internamente. Stesso discorso per l'interfaccia
IManagedInstaller.
La classe TransactedInstaller invece è
più interessante. Essa permette di installare una serie di assembly in un'unica
transazione: o tutto avviene con successo, oppure in presenza di qualche errore,
il tutto viene rollbackato. Questa classe espone la proprietà
Installers, a cui vanno
aggiunti a mano gli installer che vogliamo inserire in transazione. Dal momento
che non è inserita nell'esame 70-536, non ne parlerò, ma è interessante sapere
che c'è e su che principio funziona. Date un'occhiata all'interfaccia esposta da questa
classe e buona lettura!
Le classi AssemblyInstaller e ComponentInstaller ereditano
entrambe da Installer. La prima, in particolare, ci permette di caricare un
assembly - specificato attraverso il costruttore - e di far partire il setup
contenuto. Ovviamente, l'assembly deve derivare da Installer. L'interfaccia esposta ci permette di fare tutto quanto
necessario per agevolare il lavoro.