Esercitazione: Creare un'app del servizio Windows
Avviso
Questa documentazione non è per la versione più recente del servizio Windows. Per il contenuto più recente nei servizi Windows usando BackgroundService e il modello di servizio di lavoro, vedere:
Questo articolo illustra come creare in Visual Studio un'app di servizio di Windows che scrive messaggi in un log eventi.
Creare un servizio
Le prime operazioni da effettuare sono la creazione del progetto e l'impostazione dei valori necessari per garantire il corretto funzionamento del servizio.
Dal menu File di Visual Studio scegliere Nuovo>Progetto (o premere CTRL+MAIUSC+N) per aprire la finestra Nuovo progetto.
Trovare e selezionare il modello di progetto Windows Service (.NET Framework).
Nota
Se non viene visualizzato il modello di servizio Windows, potrebbe essere necessario installare il carico di lavoro di sviluppo desktop .NET usando Programma di installazione di Visual Studio.
Per Nome immettere MyNewService e quindi selezionare OK.
Verrà visualizzata la scheda Progettazione (Service1.cs [Progettazione] oppure Service1.vb [Progettazione]).
Il modello di progetto include una classe di componente denominata
Service1
che eredita dalla classe System.ServiceProcess.ServiceBase. Include gran parte del codice del servizio di base, ad esempio il codice per avviare il servizio.
Rinominare il servizio
Rinominare il servizio da Service1 a MyNewService.
In Esplora soluzioni selezionare Service1.cs o Service1.vb e scegliere Rinomina dal menu di scelta rapida. Rinominare il file in MyNewService.cs o MyNewService.vb e quindi premere INVIO
Una finestra popup chiederà se si vogliono rinominare tutti i riferimenti all'elemento di codice Service1.
Nella finestra popup selezionare Sì.
Nella scheda Progettazione selezionare Proprietà dal menu di scelta rapida. Nella finestra Proprietà cambiare il valore di ServiceName in MyNewService.
Selezionare Salva tutto dal menu File.
Aggiungere funzionalità al servizio
In questa sezione verrà aggiunto un log eventi personalizzato al servizio Windows. Il componente EventLog è un esempio del tipo di componente che è possibile aggiungere a un servizio di Windows.
Aggiungere la funzionalità del log eventi personalizzato
In Esplora soluzioni scegliere Visualizza Designer dal menu di scelta rapida per MyNewService.cs o MyNewService.vb.
Nella casella degli strumenti espandere Componenti e quindi trascinare il componente EventLog nella scheda Service1.cs [Design] o Service1.vb [Design].
In Esplora soluzioni scegliere Visualizza codice dal menu di scelta rapida per MyNewService.cs o MyNewService.vb.
Definire un log eventi personalizzato.
Per C#, modificare il costruttore esistente
MyNewService()
, come illustrato nel frammento di codice seguente. Per Visual Basic, aggiungere ilNew()
costruttore come illustrato nel frammento di codice seguente.public MyNewService() { InitializeComponent(); eventLog1 = new System.Diagnostics.EventLog(); if (!System.Diagnostics.EventLog.SourceExists("MySource")) { System.Diagnostics.EventLog.CreateEventSource( "MySource","MyNewLog"); } eventLog1.Source = "MySource"; eventLog1.Log = "MyNewLog"; }
' To access the constructor in Visual Basic, select New from the ' method name drop-down list. Public Sub New() MyBase.New() InitializeComponent() Me.EventLog1 = New System.Diagnostics.EventLog If Not System.Diagnostics.EventLog.SourceExists("MySource") Then System.Diagnostics.EventLog.CreateEventSource("MySource", "MyNewLog") End If EventLog1.Source = "MySource" EventLog1.Log = "MyNewLog" End Sub
Aggiungere un'istruzione
using
a MyNewService.cs (se non esiste già) o un'istruzioneImports
a MyNewService.vb per lo System.Diagnostics spazio dei nomi:using System.Diagnostics;
Imports System.Diagnostics
Selezionare Salva tutto dal menu File.
Definire quello che accade quando il servizio viene avviato
Nell'editor di codice per MyNewService.cs o MyNewService.vb individuare il OnStart metodo. Visual Studio ha creato automaticamente una definizione di metodo vuota quando è stato creato il progetto. Aggiungere codice che scriva una voce nel log eventi all'avvio del servizio:
protected override void OnStart(string[] args)
{
eventLog1.WriteEntry("In OnStart.");
}
' To access the OnStart in Visual Basic, select OnStart from the
' method name drop-down list.
Protected Overrides Sub OnStart(ByVal args() As String)
EventLog1.WriteEntry("In OnStart")
End Sub
Polling
Poiché le applicazioni di servizio sono progettate per un'esecuzione di lunga durata, generalmente eseguono operazioni di polling o di monitoraggio del sistema, che vengono configurate nel metodo OnStart. Il metodo OnStart
deve rispondere al sistema operativo dopo l'avvio del servizio, perché il sistema non rimanga bloccato.
Per impostare un semplice meccanismo di polling, usare il componente System.Timers.Timer. Il timer genera un evento Elapsed a intervalli regolari. In corrispondenza di questo evento il servizio può eseguire il monitoraggio. Per usare il componente Timer eseguire le operazioni seguenti:
- Impostare le proprietà del componente Timer nel metodo
MyNewService.OnStart
. - Avviare il timer tramite una chiamata al metodo Start.
Configurare il meccanismo di polling
Aggiungere un'istruzione
using
a MyNewService.cs o un'istruzioneImports
a MyNewService.vb per lo spazio dei nomi System.Timers:using System.Timers;
Imports System.Timers
Aggiungere il codice seguente nell'evento
MyNewService.OnStart
per configurare il meccanismo di polling:// Set up a timer that triggers every minute. Timer timer = new Timer(); timer.Interval = 60000; // 60 seconds timer.Elapsed += new ElapsedEventHandler(this.OnTimer); timer.Start();
' Set up a timer that triggers every minute. Dim timer As Timer = New Timer() timer.Interval = 60000 ' 60 seconds AddHandler timer.Elapsed, AddressOf Me.OnTimer timer.Start()
Nella classe
MyNewService
aggiungere una variabile membro. Questa contiene l'identificatore dell'evento successivo da scrivere nel log eventi:private int eventId = 1;
Private eventId As Integer = 1
Nella classe
MyNewService
aggiungere il metodoOnTimer
per gestire l'evento Timer.Elapsed:public void OnTimer(object sender, ElapsedEventArgs args) { // TODO: Insert monitoring activities here. eventLog1.WriteEntry("Monitoring the System", EventLogEntryType.Information, eventId++); }
Private Sub OnTimer(sender As Object, e As Timers.ElapsedEventArgs) ' TODO: Insert monitoring activities here. eventLog1.WriteEntry("Monitoring the System", EventLogEntryType.Information, eventId) eventId = eventId + 1 End Sub
Invece di eseguire tutto il lavoro nel thread principale, è possibile eseguire le attività tramite thread di lavoro in background. Per altre informazioni, vedere System.ComponentModel.BackgroundWorker.
Definire quello che accade quando il servizio viene arrestato
Inserire nel metodo OnStop una riga di codice che aggiunga una voce nel log eventi all'arresto del servizio:
protected override void OnStop()
{
eventLog1.WriteEntry("In OnStop.");
}
Protected Overrides Sub OnStop()
EventLog1.WriteEntry("In OnStop.")
End Sub
Definire altre azioni del servizio
È possibile eseguire l'override dei metodi OnPause, OnContinue e OnShutdown per definire ulteriori operazioni di elaborazione del componente.
Il codice seguente illustra come eseguire l'override del OnContinueMyNewService
metodo nella classe:
protected override void OnContinue()
{
eventLog1.WriteEntry("In OnContinue.");
}
Protected Overrides Sub OnContinue()
EventLog1.WriteEntry("In OnContinue.")
End Sub
Impostare lo stato del servizio
I servizi segnalano il proprio stato a Gestione controllo servizi, in modo che gli utenti possano stabilire se un servizio funziona correttamente. Per impostazione predefinita, un servizio che eredita da ServiceBase segnala un set limitato di impostazioni di stato, ovvero SERVICE_STOPPED, SERVICE_PAUSED e SERVICE_RUNNING. Se l'avvio di un servizio richiede tempo, è utile segnalare lo stato SERVICE_START_PENDING.
È possibile implementare le impostazioni di stato SERVICE_START_PENDING e SERVICE_STOP_PENDING aggiungendo codice che chiami la funzione SetServiceStatus di Windows.
Implementare lo stato corrispondente al servizio in sospeso
Aggiungere un'istruzione
using
a MyNewService.cs o un'istruzioneImports
a MyNewService.vb per lo spazio dei nomi System.Runtime.InteropServices:using System.Runtime.InteropServices;
Imports System.Runtime.InteropServices
Aggiungere il codice seguente in MyNewService.cs o in MyNewService.vb per dichiarare i valori di
ServiceState
e per aggiungere una struttura per lo stato da usare in una chiamata platform invoke:public enum ServiceState { SERVICE_STOPPED = 0x00000001, SERVICE_START_PENDING = 0x00000002, SERVICE_STOP_PENDING = 0x00000003, SERVICE_RUNNING = 0x00000004, SERVICE_CONTINUE_PENDING = 0x00000005, SERVICE_PAUSE_PENDING = 0x00000006, SERVICE_PAUSED = 0x00000007, } [StructLayout(LayoutKind.Sequential)] public struct ServiceStatus { public int dwServiceType; public ServiceState dwCurrentState; public int dwControlsAccepted; public int dwWin32ExitCode; public int dwServiceSpecificExitCode; public int dwCheckPoint; public int dwWaitHint; };
Public Enum ServiceState SERVICE_STOPPED = 1 SERVICE_START_PENDING = 2 SERVICE_STOP_PENDING = 3 SERVICE_RUNNING = 4 SERVICE_CONTINUE_PENDING = 5 SERVICE_PAUSE_PENDING = 6 SERVICE_PAUSED = 7 End Enum <StructLayout(LayoutKind.Sequential)> Public Structure ServiceStatus Public dwServiceType As Long Public dwCurrentState As ServiceState Public dwControlsAccepted As Long Public dwWin32ExitCode As Long Public dwServiceSpecificExitCode As Long Public dwCheckPoint As Long Public dwWaitHint As Long End Structure
Nota
La finestra di dialogo Gestione controllo servizi usa i membri
dwWaitHint
edwCheckpoint
della struttura SERVICE_STATUS per determinare il tempo di attesa per l'avvio o l'arresto di un servizio Windows. Se l'esecuzione dei metodiOnStart
eOnStop
è prolungata, il servizio può richiedere più tempo chiamando di nuovoSetServiceStatus
con un valore didwCheckPoint
incrementato.Nella classe
MyNewService
dichiarare la funzione SetServiceStatus usando platform invoke:[DllImport("advapi32.dll", SetLastError = true)] private static extern bool SetServiceStatus(System.IntPtr handle, ref ServiceStatus serviceStatus);
Declare Auto Function SetServiceStatus Lib "advapi32.dll" (ByVal handle As IntPtr, ByRef serviceStatus As ServiceStatus) As Boolean
Per implementare lo stato SERVICE_START_PENDING, aggiungere il codice seguente all'inizio del metodo OnStart:
// Update the service state to Start Pending. ServiceStatus serviceStatus = new ServiceStatus(); serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING; serviceStatus.dwWaitHint = 100000; SetServiceStatus(this.ServiceHandle, ref serviceStatus);
' Update the service state to Start Pending. Dim serviceStatus As ServiceStatus = New ServiceStatus() serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING serviceStatus.dwWaitHint = 100000 SetServiceStatus(Me.ServiceHandle, serviceStatus)
Aggiungere codice alla fine del metodo
OnStart
per impostare lo stato su SERVICE_RUNNING:// Update the service state to Running. serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING; SetServiceStatus(this.ServiceHandle, ref serviceStatus);
' Update the service state to Running. serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING SetServiceStatus(Me.ServiceHandle, serviceStatus)
(Facoltativo) Se OnStop è un metodo a esecuzione prolungata, ripetere questa procedura nel metodo
OnStop
. Implementare lo stato SERVICE_STOP_PENDING e restituire lo stato SERVICE_STOPPED prima che il metodoOnStop
esca.Ad esempio:
// Update the service state to Stop Pending. ServiceStatus serviceStatus = new ServiceStatus(); serviceStatus.dwCurrentState = ServiceState.SERVICE_STOP_PENDING; serviceStatus.dwWaitHint = 100000; SetServiceStatus(this.ServiceHandle, ref serviceStatus); // Update the service state to Stopped. serviceStatus.dwCurrentState = ServiceState.SERVICE_STOPPED; SetServiceStatus(this.ServiceHandle, ref serviceStatus);
' Update the service state to Stop Pending. Dim serviceStatus As ServiceStatus = New ServiceStatus() serviceStatus.dwCurrentState = ServiceState.SERVICE_STOP_PENDING serviceStatus.dwWaitHint = 100000 SetServiceStatus(Me.ServiceHandle, serviceStatus) ' Update the service state to Stopped. serviceStatus.dwCurrentState = ServiceState.SERVICE_STOPPED SetServiceStatus(Me.ServiceHandle, serviceStatus)
Aggiungere programmi di installazione al servizio
Prima di eseguire un servizio di Windows, è necessario installarlo, ovvero registrarlo con Gestione controllo servizi. Per gestire i dettagli della registrazione, aggiungere programmi di installazione al progetto.
Dal menu di scelta rapida per MyNewService.cs o MyNewService.vb in Esplora soluzioni scegliere Visualizza finestra di progettazione.
Nella visualizzazione Progettazione selezionare l'area di sfondo e quindi scegliere Aggiungi programma di installazione dal menu di scelta rapida.
Per impostazione predefinita, Visual Studio aggiunge al progetto una classe di componenti denominata
ProjectInstaller
, contenente due programmi di installazione. Questi programmi di installazione sono destinati al servizio e al processo associato al servizio stesso.Nella visualizzazione Progettazione per ProjectInstaller selezionare serviceInstaller1 per un progetto Visual C# o ServiceInstaller1 per un progetto Visual Basic e quindi scegliere Proprietà dal menu di scelta rapida.
Nella finestra Proprietà verificare che la proprietà ServiceName sia impostata su MyNewService.
Aggiungere testo alla proprietà Description, ad esempio A sample service (Servizio di esempio).
Questo testo, che viene visualizzato nella colonna Descrizione della finestra Servizi, descrive il servizio all'utente.
Aggiungere testo alla proprietà DisplayName, ad esempio, MyNewService Display Name (Nome visualizzato di MyNewService).
Questo testo viene visualizzato nella colonna Nome visualizzato della finestra Servizi. Questo nome può essere diverso dalla proprietà ServiceName, che corrisponde al nome usato dal sistema, ad esempio il nome usato con il comando
net start
per avviare il servizio.Impostare la proprietà StartType su Automatic dall'elenco a discesa.
Al termine, la finestra Proprietà dovrebbe avere l'aspetto della figura seguente:
Nella visualizzazione Progettazione per ProjectInstaller scegliere serviceProcessInstaller1 per un progetto Visual C# o ServiceProcessInstaller1 per un progetto Visual Basic e quindi scegliere Proprietà dal menu di scelta rapida. Impostare la proprietà Account su LocalSystem dall'elenco a discesa.
Questa impostazione consente di installare ed eseguire il servizio tramite l'account di sistema locale.
Importante
L'account LocalSystem dispone di ampie autorizzazioni, tra cui la possibilità di scrivere nel log eventi. Usare questo account con attenzione, perché potrebbe aumentare il rischio di attacchi da parte di software dannoso. Per altre attività, è opportuno usare l'account LocalService che opera come utente senza privilegi nel computer locale e presenta credenziali anonime a tutti i server remoti. Questo esempio non riesce se si tenta di usare l'account LocalService perché sono necessarie le autorizzazioni per scrivere nel log eventi.
Per altre informazioni sui programmi di installazione, vedere Procedura: Aggiungere programmi di installazione all'applicazione di servizio.
(Facoltativo) Impostare i parametri di avvio
Nota
Prima di decidere di aggiungere parametri di avvio, valutare se sia l'approccio migliore per passare informazioni al servizio. Anche se i parametri di avvio sono facili da usare e da analizzare e gli utenti possono facilmente eseguirne l'override, possono essere più difficili da individuare e da usare senza documentazione. In genere, se il servizio richiede diversi parametri di avvio, è consigliabile usare il Registro di sistema o un file di configurazione.
Un servizio di Windows può accettare argomenti della riga di comando o parametri di avvio. Quando si aggiunge il codice ai parametri di avvio del processo, gli utenti possono avviare il servizio con parametri di avvio personalizzati nella finestra delle proprietà del servizio. Questi parametri di avvio, tuttavia, non vengono mantenuti al successivo avvio del servizio. Per impostare parametri di avvio in modo permanente, impostarli nel Registro di sistema.
Ogni servizio di Windows ha una voce del Registro di sistema nella sottochiave HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services. Nella sottochiave di ogni servizio usare la sottochiave Parameters per archiviare le informazioni a cui il servizio può accedere. È possibile usare i file di configurazione dell'applicazione per un servizio di Windows in modo analogo a come avviene per gli altri tipi di programmi. Per codice di esempio, vedere ConfigurationManager.AppSettings.
Per aggiungere parametri di avvio
Selezionare Program.cs o MyNewService.Designer.vb e quindi scegliere Visualizza codice dal menu di scelta rapida. Nel metodo
Main
modificare il codice aggiungendo un parametro di input e passare quest'ultimo al costruttore del servizio:static void Main(string[] args) { ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { new MyNewService(args) }; ServiceBase.Run(ServicesToRun); }
Shared Sub Main(ByVal cmdArgs() As String) Dim ServicesToRun() As System.ServiceProcess.ServiceBase = New System.ServiceProcess.ServiceBase() {New MyNewService(cmdArgs)} System.ServiceProcess.ServiceBase.Run(ServicesToRun) End Sub
In MyNewService.cs o MyNewService.vb modificare il costruttore
MyNewService
in modo che elabori il parametro di input come segue:using System.Diagnostics; public MyNewService(string[] args) { InitializeComponent(); string eventSourceName = "MySource"; string logName = "MyNewLog"; if (args.Length > 0) { eventSourceName = args[0]; } if (args.Length > 1) { logName = args[1]; } eventLog1 = new EventLog(); if (!EventLog.SourceExists(eventSourceName)) { EventLog.CreateEventSource(eventSourceName, logName); } eventLog1.Source = eventSourceName; eventLog1.Log = logName; }
Imports System.Diagnostics Public Sub New(ByVal cmdArgs() As String) InitializeComponent() Dim eventSourceName As String = "MySource" Dim logName As String = "MyNewLog" If (cmdArgs.Count() > 0) Then eventSourceName = cmdArgs(0) End If If (cmdArgs.Count() > 1) Then logName = cmdArgs(1) End If eventLog1 = New EventLog() If (Not EventLog.SourceExists(eventSourceName)) Then EventLog.CreateEventSource(eventSourceName, logName) End If eventLog1.Source = eventSourceName eventLog1.Log = logName End Sub
Questo codice imposta l'origine e il nome del log dell'evento in base ai parametri di avvio specificati dall'utente. Se non vengono specificati argomenti, usa i valori predefiniti.
Per specificare gli argomenti della riga di comando, aggiungere il codice seguente alla
ProjectInstaller
classe in ProjectInstaller.cs o ProjectInstaller.vb:protected override void OnBeforeInstall(IDictionary savedState) { string parameter = "MySource1\" \"MyLogFile1"; Context.Parameters["assemblypath"] = "\"" + Context.Parameters["assemblypath"] + "\" \"" + parameter + "\""; base.OnBeforeInstall(savedState); }
Protected Overrides Sub OnBeforeInstall(ByVal savedState As IDictionary) Dim parameter As String = "MySource1"" ""MyLogFile1" Context.Parameters("assemblypath") = """" + Context.Parameters("assemblypath") + """ """ + parameter + """" MyBase.OnBeforeInstall(savedState) End Sub
In genere, questo valore contiene il percorso completo del file eseguibile per il servizio di Windows. Perché il servizio venga avviato correttamente, è necessario usare le virgolette per il percorso e per ogni singolo parametro. È possibile cambiare i parametri nella voce del Registro di sistema ImagePath per cambiare i parametri di avvio del servizio di Windows. Una soluzione migliore, tuttavia, consiste nel cambiare il valore a livello di codice e nell'esporre la funzionalità in un modo semplice da usare, ad esempio tramite un'utilità di gestione o di configurazione.
Compilare il servizio
In Esplora soluzioni scegliere Proprietà dal menu di scelta rapida per il progetto MyNewService.
Verranno visualizzate le pagine delle proprietà per il progetto.
Nell'elenco Oggetto di avvio della scheda Applicazione scegliere MyNewService.Program o Sub Main per i progetti Visual Basic.
Per compilare il progetto, in Esplora soluzioni scegliere Compila dal menu di scelta rapida del progetto o premere CTRL+MAIUSC+B.
Installare il servizio
Una volta compilato il servizio Windows, è possibile installarlo. Per installare un servizio di Windows, è necessario avere credenziali di amministratore per il computer in cui il servizio è installato.
Aprire il Prompt dei comandi per gli sviluppatori per Visual Studio con credenziali amministrative.
Nel prompt dei comandi per gli sviluppatori per Visual Studio passare alla cartella che contiene l'output del progetto (per impostazione predefinita, la sottodirectory \bin\Debug del progetto).
Immettere il comando seguente:
installutil MyNewService.exe
Se il servizio viene installato correttamente, il comando segnala l'esito positivo.
Se il sistema non riesce a trovare installutil.exe, assicurarsi che sia presente nel computer in uso. Questo strumento viene installato con .NET Framework nella cartella %windir%\Microsoft.NET\Framework[64]\<framework.> Il percorso predefinito per la versione a 64 bit, ad esempio, è %windir%\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe.
Se il processo installutil.exe ha esito negativo, controllare il log di installazione per determinarne il motivo. Per impostazione predefinita, il log è nella stessa cartella del file eseguibile del servizio. L'installazione può non riuscire se:
- La classe RunInstallerAttribute non è presente nella classe
ProjectInstaller
. - L'attributo non è impostato su
true
. - La classe
ProjectInstaller
non è definita comepublic
.
- La classe RunInstallerAttribute non è presente nella classe
Per altre informazioni, vedere Procedura: Installare e disinstallare i servizi.
Avviare ed eseguire il servizio
In Windows aprire l'app desktop Servizi. Premere Windows+R per aprire la casella Esegui , immettere services.msc, quindi premere INVIO o selezionare OK.
Il servizio verrà elencato in Servizi, in ordine alfabetico in base al nome visualizzato impostato.
Per avviare il servizio, scegliere Avvia dal menu di scelta rapida del servizio.
Per arrestare il servizio, scegliere Arresta dal menu di scelta rapida del servizio.
(Facoltativo) Dalla riga di comando usare i comandi net start <nome servizio> e net stop <nome servizio> per avviare e arrestare il servizio.
Verificare l'output del log eventi del servizio
In Windows aprire l'app desktop Visualizzatore eventi. Immettere Visualizzatore eventi nella barra di ricerca di Windows e quindi selezionare Visualizzatore eventi dai risultati della ricerca.
Suggerimento
In Visual Studio è possibile accedere ai log eventi aprendo Esplora server dal menu Visualizza, o premendo CTRL+ALT+S, ed espandendo il nodo Log eventi per il computer locale.
Nel Visualizzatore eventi espandere Registri applicazioni e servizi.
Individuare l'elenco per MyNewLog (o MyLogFile1, se è stata seguita la procedura per aggiungere argomenti della riga di comando) ed espanderlo. Verranno visualizzate le voci per le due azioni (avvio e arresto) eseguite dal servizio.
Pulire le risorse
Se l'app del servizio di Windows non è più necessaria, è possibile rimuoverla.
Aprire il Prompt dei comandi per gli sviluppatori per Visual Studio con credenziali amministrative.
Nella finestra Prompt dei comandi per gli sviluppatori per Visual Studio passare alla cartella contenente l'output del progetto.
Immettere il comando seguente:
installutil.exe /u MyNewService.exe
Se il servizio viene disinstallato correttamente, il comando segnala che il servizio è stato rimosso correttamente. Per altre informazioni, vedere Procedura: Installare e disinstallare i servizi.
Passaggi successivi
Dopo aver creato il servizio, è possibile:
Creare un programma di installazione autonomo che gli altri utenti possono usare per installare il servizio di Windows. Usare il set di strumenti WiX per creare un programma di installazione per un servizio di Windows. Per altre idee, vedere Creare un pacchetto di installazione.
Esaminare il componente ServiceController, che consente di inviare comandi al servizio installato.
Anziché creare il log eventi durante l'esecuzione dell'applicazione, crearlo durante l'installazione dell'applicazione stessa tramite il programma di installazione. Il log eventi viene eliminato dal programma di installazione quando si disinstalla l'applicazione. Per altre informazioni, vedere EventLogInstaller.