C# Creare un Servizio Windows - Part3
Riepilogo Link:
Parte 1
Parte 2
Parte 3
In quest’ultima parte, quella sicuramente più interessante verrà descritto come visualizzare una Form Custom nella quale impostare un valore nel file di configurazione, nel nostro caso imposteremo due valori:
1) il tempo di intervallo del timer,
2) una folder nella quale salvare eventuali file di esempio
Prima di tutto creiamo il file di configurazione nel quale inseriremo le due voci:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="timerInterval" value="10000"/>
<add key="folderTemp" value="c:\temp"/>
</appSettings>
</configuration>
Adesso creiamo una WindowsForm dalla quale andremo ad impostare il tempo di intervallo del timer in millisecondi e una folder nella quale salvare dei file di testo:
Nel costruttore della nostra Form andremo a leggere i valori di default, impostati nel file di configurazione, per prevalorizzare le nostre textBox:
public FrmSetTimer()
{
InitializeComponent();
Configuration c = ConfigurationManager.OpenExeConfiguration(System.Reflection.Assembly.GetExecutingAssembly().Location);
AppSettingsSection section = (AppSettingsSection)c.GetSection("appSettings");
txtFolder.Text = section.Settings["folderTemp"].Value;
txtTimer.Text = section.Settings["timerInterval"].Value;
}
Sul click del pulsante sfoglia andremo ad utilizzare un oggetto “FolderBrowserDialog” per poter far selezionare una directory dall’utente:
private void btnSfoglia_Click(object sender, EventArgs e)
{
using (var folderDialog = new FolderBrowserDialog())
{
folderDialog.RootFolder = Environment.SpecialFolder.MyComputer;
folderDialog.SelectedPath = Environment.GetFolderPath(folderDialog.RootFolder);
if (folderDialog.ShowDialog() == DialogResult.OK)
{
txtFolder.Text = folderDialog.SelectedPath;
}
}
}
Sul click del pulsante “Salva” andremo a salvare i valori nel file di configurazione della nostra applicazione:
private void btnSalva_Click(object sender, EventArgs e)
{
Configuration c = ConfigurationManager.OpenExeConfiguration(System.Reflection.Assembly.GetExecutingAssembly().Location);
AppSettingsSection section = (AppSettingsSection)c.GetSection("appSettings");
section.Settings["folderTemp"].Value = txtFolder.Text;
section.Settings["timerInterval"].Value = txtTimer.Text;
c.Save();
this.Close();
}
Adesso abbiam creato la nostra form custom ma dobbiamo intercettare l’evento OnAfterInstall per poterla mostrare all’utente.
Ci posizioniamo nel file projectInstaller.cs e richiamiamo l’override del metodo OnAfterInstall, di seguito il codice:
protected override void OnAfterInstall(IDictionary savedState)
{
Thread temp = new Thread(new ThreadStart(ShowCustomDialog));
temp.SetApartmentState(ApartmentState.STA);
temp.Start();
while (temp.ThreadState == ThreadState.Running)
Thread.Sleep(2000);
}
Come potete notare la form la stiamo eseguendo in un thread a parte, questo perché al suo interno viene utilizzato un oggetto di tipo “FolderBrowserDialog” che sembra funzionare solo se viene eseguito in un thread impostato su “SingleThreadApartment”, infatti la riga fondamentale è proprio la seguente: “temp.SetApartmentState(ApartmentState.STA);”
Nel nostro metodo “ShowCustomDialog” non faremo altro che visualizzare la form:
private void ShowCustomDialog()
{
FrmSetTimer frmSetConfigParam = new FrmSetTimer();
frmSetConfigParam.ShowDialog();
}
Adesso durante l’installazione del nostro progetto ci verrà mostrata un immagine simile alla seguente:
Riepilogo:
In questo post, diviso in tre sezioni, abbiam visto come:
- creare un servizio windows ed il relativo Installer per aggiungerlo tra i servizi Windows,
- creare un progetto di setup per l’installazione,
- personalizzare un installazione modificando ad esempio il file di configurazione,
- utilizzare l’oggetto “FolderBrowserDialog” in una installazione personalizzata
Spero che possa esservi di aiuto,
Saluti Fabio