Tutorial: Erstellen einer Windows-Dienst-App
Warnung
Diese Dokumentation gilt nicht für die neueste Version des Windows-Diensts. Die neuesten Inhalte zu Windows-Diensten mit BackgroundService und die Workerdienstvorlage finden Sie unter:
In diesem Artikel wird beschrieben, wie Sie eine Windows-Dienstanwendung in Visual Studio erstellen, die Meldungen in ein Ereignisprotokoll schreibt.
Erstellen eines Diensts
Erstellen Sie zunächst das Projekt, und legen Sie die Werte fest, die für die korrekte Funktion des Diensts erforderlich sind.
Wählen Sie in Visual Studio auf der Menüleiste DateiNeu>Projekt aus (oder drücken Sie STRG+UMSCHALT+N), um das Fenster Neues Projekt zu öffnen.
Suchen Sie die Projektvorlage Windows-Dienst (.NET Framework), und wählen Sie sie aus.
Hinweis
Wenn die Vorlage Windows-Dienst nicht angezeigt wird, müssen Sie möglicherweise mithilfe des Visual Studio-Installers die Workload .NET-Desktopentwicklung installieren.
Geben Sie als NameMyNewService ein, und klicken Sie dann auf OK.
Die Registerkarte Design wird angezeigt (Service1.cs [Design] oder Service1.vb [Design] ).
Die Projektvorlage beinhaltet eine Komponentenklasse mit dem Namen
Service1
, die von System.ServiceProcess.ServiceBase erbt. Sie enthält einen großen Teil des grundlegenden Dienstcodes, etwa den Code zum Starten des Diensts.
Umbenennen des Diensts
Benennen Sie den Dienst von Service1 in MyNewService um.
Wählen Sie im Projektmappen-Explorer die Datei Service1.cs oder Service1.vb aus, und klicken Sie im Kontextmenü auf Umbenennen. Nennen Sie die Datei MyNewService.cs oder MyNewService.vb, und drücken Sie dann die EINGABETASTE.
Daraufhin wird ein Popupfenster angezeigt, in dem Sie gefragt werden, ob Sie alle Verweise auf das Codeelement Service1 umbenennen möchten.
Wählen Sie im Popupfenster Ja aus.
Wählen Sie in der Registerkarte Design aus dem Kontextmenü Eigenschaften aus. Ändern Sie im Fenster Eigenschaften den Wert für ServiceName in MyNewService.
Wählen Sie im Menü Datei die Option Alle speichern aus.
Hinzufügen von Features zum Dienst
In diesem Abschnitt fügen Sie dem Windows-Dienst ein benutzerdefiniertes Ereignisprotokoll hinzu. Die EventLog-Komponente wird als Beispiel für die Art von Komponente verwendet, die Sie einem Windows-Dienst hinzufügen können.
Hinzufügen einer benutzerdefinierten Ereignisprotokollfunktion
Öffnen Sie im Projektmappen-Explorer das Kontextmenü für MyNewService.cs oder MyNewService.vb, und wählen Sie dann Designer anzeigen aus.
Erweitern Sie in der Toolbox die Option Komponenten, und ziehen Sie dann die EventLog-Komponente auf eine der Registerkarten Service1.cs [Design] oder Service1.vb [Design].
Öffnen Sie im Projektmappen-Explorer das Kontextmenü für MyNewService.cs oder MyNewService.vb, und wählen Sie dann Code anzeigen aus.
Definieren Sie ein benutzerdefiniertes Ereignisprotokoll.
Wenn Sie C# verwenden, bearbeiten Sie den vorhandenen
MyNewService()
-Konstruktor, wie im folgenden Codeschnipsel gezeigt. Wenn Sie Visual Basic verwenden, fügen Sie denNew()
-Konstruktor hinzu, wie im folgenden Codeschnipsel gezeigt.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
Fügen Sie für den Namespace System.Diagnostics eine
using
-Anweisung in der Datei MyNewService.cs hinzu (sofern diese nicht bereits vorhanden ist) bzw. fügen Sie eineImports
-Anweisung zur Datei MyNewService.vb hinzu:using System.Diagnostics;
Imports System.Diagnostics
Wählen Sie im Menü Datei die Option Alle speichern aus.
Definieren, was beim Starten des Diensts ausgeführt wird
Suchen Sie im Code-Editor für MyNewService.cs bzw. MyNewService.vb nach der OnStart-Methode. Visual Studio hat beim Erstellen des Projekts automatisch eine leere Methodendefinition erstellt. Fügen Sie Code hinzu, der beim Starten des Diensts einen Eintrag in das Ereignisprotokoll schreibt:
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
Abrufen
Da eine Dienstanwendung mit langer Laufzeit entworfen wird, fragt sie in der Regel das System ab oder überwacht es. Dies haben Sie in der OnStart-Methode eingerichtet. Die OnStart
-Methode muss zum Betriebssystem zurückkehren, sobald die Ausführung des Dienstes begonnen hat, damit das System nicht blockiert wird.
Mit der System.Timers.Timer-Komponente können Sie einen einfachen Abrufmechanismus einrichten. Der Timer löst in regelmäßigen Intervallen ein Elapsed-Ereignis aus. Zu diesem Zeitpunkt kann Ihr Dienst die Überwachung durchführen. Sie verwenden die Timer-Komponente folgendermaßen:
- Legen Sie die Eigenschaften der Timer-Komponente in der
MyNewService.OnStart
-Methode fest. - Starten Sie den Timer durch Aufrufen der Start-Methode.
Einrichten des Abrufmechanismus
Fügen Sie den System.Timers-Namespace hinzu, indem Sie die
using
-Anweisung in der Datei MyNewService.cs bzw. dieImports
-Anweisung in der Datei MyNewService.vb verwenden:using System.Timers;
Imports System.Timers
Fügen Sie im
MyNewService.OnStart
-Ereignis den folgenden Code ein, um den Abrufmechanismus einzurichten:// 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()
Fügen Sie der
MyNewService
-Klasse eine Membervariable hinzu. Sie enthält den Bezeichner des nächsten Ereignisses, das in das Ereignisprotokoll geschrieben werden soll:private int eventId = 1;
Private eventId As Integer = 1
Fügen Sie der
MyNewService
-Klasse dieOnTimer
-Methode hinzu, um das Timer.Elapsed-Ereignis zu verarbeiten: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
Anstatt alle Aufgaben auf dem Hauptthread auszuführen, können Sie Aufgaben mithilfe von Arbeitsthreads im Hintergrund ausführen. Weitere Informationen finden Sie unter System.ComponentModel.BackgroundWorker.
Definieren, was beim Beenden des Diensts ausgeführt wird
Fügen Sie der Methode OnStop eine Codezeile hinzu, die beim Beenden des Diensts einen Eintrag zum Ereignisprotokoll hinzufügt:
protected override void OnStop()
{
eventLog1.WriteEntry("In OnStop.");
}
Protected Overrides Sub OnStop()
EventLog1.WriteEntry("In OnStop.")
End Sub
Definieren weiterer Aktionen für den Dienst
Sie können die Methoden OnPause, OnContinue und OnShutdown überschreiben, um zusätzliche Verarbeitungsschritte für Ihre Komponente zu definieren.
Das folgende Codebeispiel zeigt, wie Sie die OnContinue-Methode in der MyNewService
-Klasse überschreiben können:
protected override void OnContinue()
{
eventLog1.WriteEntry("In OnContinue.");
}
Protected Overrides Sub OnContinue()
EventLog1.WriteEntry("In OnContinue.")
End Sub
Festlegen des Dienststatus
Dienste melden ihren Status an den Dienststeuerungs-Manager, damit Benutzer erkennen können, ob ein Dienst ordnungsgemäß ausgeführt wird. Standardmäßig meldet ein Dienst, der von ServiceBase erbt, eine begrenzte Anzahl von Statuseinstellungen. Dazu gehören SERVICE_STOPPED, SERVICE_PAUSED und SERVICE_RUNNING. Wenn es etwas länger dauert, bis ein Dienst startet, kann es hilfreich sein, den Status SERVICE_START_PENDING zu melden.
Sie können auch die Statuseinstellungen SERVICE_START_PENDING und SERVICE_STOP_PENDING durch Hinzufügen von Code implementieren, der in Windows die Funktion SetServiceStatus aufruft.
Implementieren des Dienststatus SERVICE_PENDING
Fügen Sie den System.Runtime.InteropServices-Namespace hinzu, indem Sie die
using
-Anweisung in der Datei MyNewService.cs bzw. dieImports
-Anweisung in der Datei MyNewService.vb verwenden:using System.Runtime.InteropServices;
Imports System.Runtime.InteropServices
Fügen Sie MyNewService.cs bzw. MyNewService.vb folgenden Code hinzu, um die
ServiceState
-Werte zu deklarieren und um eine Struktur für den Status hinzuzufügen, die Sie in einem Plattformaufruf verwenden: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
Hinweis
Der Dienststeuerungs-Manager verwendet die Member
dwWaitHint
unddwCheckpoint
der SERVICE_STATUS-Struktur, um zu bestimmen, wie lange bis zum Starten oder Herunterfahren eines Windows-Diensts gewartet werden muss. Wenn Ihre MethodenOnStart
undOnStop
eine lange Ausführungszeit haben, kann Ihr Dienst durch das erneute Aufrufen vonSetServiceStatus
mit einem erhöhtendwCheckPoint
-Wert mehr Zeit anfordern.Deklarieren Sie nun in der Klasse
MyNewService
die Funktion SetServiceStatus mithilfe eines Plattformaufrufs:[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
Soll der Status Start SERVICE_START_PENDING implementiert werden, fügen Sie den folgenden Code am Anfang der OnStart-Methode hinzu:
// 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)
Fügen Sie am Ende der
OnStart
-Methode Code hinzu, um den Status SERVICE_RUNNING festzulegen:// 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)
(Optional) Wenn OnStop eine Methode mit langer Laufzeit ist, wiederholen Sie diese Prozedur in der Methode
OnStop
. Implementieren Sie den Status SERVICE_STOP_PENDING und geben Sie den SERVICE_STOPPED-Status zurück, bevor dieOnStop
-Methode endet.Zum Beispiel:
// 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)
Hinzufügen von Installern zum Dienst
Bevor Sie einen Windows-Dienst ausführen können, müssen Sie ihn bei der Installation im Dienststeuerungs-Manager registrieren. Sie können Ihrem Projekt Installer hinzufügen, um die Registrierungsdetails zu verarbeiten.
Öffnen Sie im Projektmappen-Explorer das Kontextmenü für MyNewService.cs oder MyNewService.vb, und wählen Sie dann Designer anzeigen aus.
Wählen Sie in der Ansicht Design den Hintergrundbereich aus, und wählen Sie dann im Kontextmenü Installer hinzufügen aus.
Standardmäßig fügt Visual Studio Ihrem Projekt eine Komponentenklasse namens
ProjectInstaller
hinzu, die zwei Installer beinhaltet. Diese Installer sind für Ihren Dienst und den zum Dienst gehörigen Prozess bestimmt.Klicken Sie in der Ansicht Design für ProjectInstaller auf serviceInstaller1, wenn es sich um ein Visual C#-Projekt handelt, bzw. auf ServiceInstaller1 , wenn es sich um ein Visual Basic-Projekt handelt, und wählen Sie dann im Kontextmenü Eigenschaften aus.
Vergewissern Sie sich im Fenster Eigenschaften, dass die ServiceName-Eigenschaft auf MyNewService festgelegt ist.
Fügen Sie der Description-Eigenschaft Text hinzu, z. B. Ein Beispieldienst.
Dieser Text wird im Fenster Dienste in der Spalte Beschreibung angezeigt und beschreibt den Dienst für den Benutzer.
Fügen Sie in der DisplayName-Eigenschaft Text hinzu, z. B. MyNewService-Anzeigename.
Dieser Text wird im Fenster Dienste in der Spalte Anzeigename angezeigt. Dieser Name kann sich von der ServiceName-Eigenschaft unterscheiden, die dem Namen entspricht, der vom System verwendet wird (z. B. bei Verwendung des
net start
-Befehls zum Starten des Diensts).Legen Sie die StartType-Eigenschaft über die Dropdownliste auf Automatic fest.
Wenn Sie diesen Vorgang abgeschlossen haben, sollte das Eigenschaften-Fenster der folgenden Abbildung entsprechen:
Klicken Sie in der Ansicht Design für ProjectInstaller auf serviceProcessInstaller1, wenn es sich um ein Visual C#-Projekt handelt, bzw. auf ServiceProcessInstaller1 , wenn es sich um ein Visual Basic-Projekt handelt, und wählen Sie dann im Kontextmenü Eigenschaften aus. Legen Sie die Account-Eigenschaft über die Dropdownliste auf LocalSystem fest.
Diese Einstellung installiert den Dienst und führt ihn mithilfe des lokalen Systemkontos aus.
Wichtig
Das Konto LocalSystem verfügt über ein breites Berechtigungsspektrum, einschließlich der Berechtigung zum Schreiben in das Ereignisprotokoll. Bei der Verwendung dieses Kontos ist allerdings Vorsicht geboten, da sich dadurch das Risiko von Malware-Angriffen erhöhen kann. Für andere Aufgaben sollten Sie das Konto LocalService verwenden, das auf dem lokalen Computer als Benutzer ohne Berechtigungen fungiert. Remoteservern werden anonyme Anmeldeinformationen übergeben. Dieses Beispiel schlägt fehl, wenn Sie versuchen, das LocalService -Konto zu verwenden, da zum Schreiben in das Ereignisprotokoll eine Genehmigung benötigt wird.
Weitere Informationen zu Installern finden Sie unter Vorgehensweise: Hinzufügen von Installern zur Dienstanwendung.
(Optional) Festlegen der Startparameter
Hinweis
Bevor Sie sich entscheiden, die Startparameter hinzuzufügen, ziehen Sie in Betracht, ob dies die beste Möglichkeit für die Übertragung von Informationen an Ihren Dienst ist. Obwohl Startparameter einfach zu verwenden und zu analysieren sind, und Benutzer sie leicht überschreiben können, sind sie möglicherweise ohne Dokumentation schwerer zu erkennen und zu verwenden. Wenn der Dienst mehrere Startparameter erfordert, sollten Sie in der Regel stattdessen die Verwendung des Verzeichnisses oder einer Konfigurationsdatei erwägen.
Ein Windows-Dienst akzeptiert Befehlszeilenargumente oder Startparameter. Wenn Sie einen Code zum Startparameterprozess hinzufügen, können Benutzer den Dienst mithilfe des Fensters „Diensteigenschaften“ mit ihren eigenen benutzerdefinierten Startparametern starten. Diese Startparameter werden jedoch nicht beim nächsten Start des Dienst beibehalten. Wenn Sie Startparameter dauerhaft festlegen möchten, müssen Sie sie im Verzeichnis festlegen.
Jeder Windows-Dienst hat einen Verzeichniseintrag unter dem Unterschlüssel HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services. Verwenden Sie unter dem Unterschlüssel jedes Diensts den Unterschlüssel Parameter zum Speichern von Informationen, auf die Ihr Dienst zugreifen kann. Sie können Konfigurationsdateien für einen Windows-Dienst genauso wie für andere Arten von Programmen verwenden. Beispielcode finden Sie unter ConfigurationManager.AppSettings.
Hinzufügen von Startparametern
Wählen Sie Program.cs oder MyNewService.Designer.vb aus, und wählen Sie dann im Kontextmenü Code anzeigen aus. Ändern Sie in der
Main
-Methode den Code, sodass ein Eingabeparameter hinzugefügt wird, und übergeben Sie ihn an den Dienstkonstruktor: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
Ändern Sie in MyNewService.cs bzw. MyNewService.vb den
MyNewService
-Konstruktor, sodass der Eingabeparameter folgendermaßen verarbeitet wird: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
Diese Code legt die Ereignisquelle und den Protokollnamen gemäß der Startparameter fest, die der Benutzer angibt. Wenn keine Argumente angegeben werden, werden Standardwerte verwendet.
Sollen Befehlszeilenargumente angegeben werden, fügen Sie der
ProjectInstaller
-Klasse in ProjectInstaller.cs bzw. ProjectInstaller.vb den folgenden Code hinzu: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
Dieser Wert enthält in der Regel den vollständigen Pfad zur ausführbaren Datei des Windows-Diensts. Die Anführungszeichen rund um den Pfad und um jeden einzelnen Parameter sind erforderlich, um den Dienst korrekt zu starten. Ein Benutzer kann die Parameter im ImagePath-Verzeichniseintrag ändern, um die Startparameter für den Windows-Dienst zu ändern. Besser ist es jedoch, den Wert programmgesteuert zu ändern und die Funktionalität in einer benutzerfreundlichen Weise verfügbar zu machen, z. B. mithilfe eines Verwaltungs- oder Konfigurationshilfsprogramms.
Erstellen des Diensts
Wählen Sie im Projektmappen-Explorer aus dem Kontextmenü des MyNewService-Projekts die Option Eigenschaften aus.
Die Eigenschaftenseiten für Ihr Projekt werden angezeigt.
Klicken Sie in der Registerkarte Anwendung in der Liste Startobjekt auf MyNewService.Program, oder auf Sub Main, wenn es sich um ein Visual Basic-Projekt handelt.
Wählen Sie im Projektmappen-Explorer aus dem Kontextmenü des Projekts Erstellen aus, um das Projekt zu erstellen (oder drücken Sie STRG+UMSCHALT+B).
Installieren des Diensts
Nachdem Sie den Windows-Dienst nun erstellt haben, können Sie ihn installieren. Soll ein Windows-Dienst installiert werden, müssen Sie über Administratorberechtigungen für den Computer verfügen, auf dem Sie ihn installieren.
Öffnen Sie die Developer-Eingabeaufforderung für Visual Studio mit Administratoranmeldeinformationen.
Navigieren Sie in der Developer-Eingabeaufforderung für Visual Studio zu dem Ordner, der die Ausgabe Ihres Projekts enthält (standardmäßig das Unterverzeichnis \bin\Debug Ihres Projekts).
Geben Sie folgenden Befehl ein:
installutil MyNewService.exe
Wenn der Dienst erfolgreich installiert wurde, meldet der Befehl Erfolg.
Wenn das System die Datei installutil.exe nicht finden kann, stellen Sie sicher, dass sie auf Ihrem Computer vorhanden ist. Dieses Tool wird zusammen mit .NET Framework im Ordner %windir%\Microsoft.NET\Framework[64]\<Frameworkversion> installiert. Der Standardpfad für die 64-Bit-Version lautet beispielsweise %windir%\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe.
Wenn der Prozess installutil.exe fehlschlägt, überprüfen Sie das Installationsprotokoll, um die Gründe zu bestimmen. Standardmäßig befindet sich das Protokoll im gleichen Ordner wie die ausführbare Datei des Diensts. Die Installation kann aus folgenden Gründen fehlschlagen:
- Die RunInstallerAttribute-Klasse ist in der
ProjectInstaller
-Klasse nicht vorhanden. - Das Attribut ist nicht auf
true
festgelegt. - Die
ProjectInstaller
-Klasse ist nicht alspublic
definiert.
- Die RunInstallerAttribute-Klasse ist in der
Weitere Informationen finden Sie unter Vorgehensweise: Installieren und Deinstallieren von Diensten.
Starten und Ausführen des Diensts
Öffnen Sie in Windows die Desktop-App Dienste. Drücken Sie Windows+R, um das Feld Ausführen zu öffnen, geben Sie dann services.msc ein, und drücken Sie die EINGABETASTE, oder klicken Sie auf OK.
Ihr Dienst sollte in Dienste alphabetisch nach dem Anzeigenamen aufgeführt sein, den Sie für ihn festgelegt haben.
Der Dienst wird gestartet, wenn Sie im Kontextmenü des Diensts Starten auswählen.
Der Dienst wird angehalten, wenn Sie im Kontextmenü des Diensts Stopp auswählen.
(Optional) Über die Befehlszeile können Sie die Befehle net start <Dienstname> und net stop <Dienstname> verwenden, um Ihren Dienst zu starten und zu stoppen.
Überprüfen der Ereignisprotokollausgabe des Diensts
Öffnen Sie in Windows die Desktop-App Event Viewer. Geben Sie in der Windows-Suchleiste Event Viewer ein, und wählen Sie dann in den Suchergebnissen Event Viewer aus.
Tipp
In Visual Studio können Sie auf Ereignisprotokolle zugreifen, indem Sie über das Menü Anzeigen den Server-Explorer öffnen (oder STRG+ALT+S drücken) und den Knoten Ereignisprotokolle für den lokalen Computer aufklappen.
Klappen Sie in der EreignisanzeigeAnwendungs- und Dienstprotokolle auf.
Suchen Sie den Eintrag für MyNewLog (oder MyLogFile1, wenn Sie das Verfahren befolgt haben, um Befehlszeilenargumente hinzuzufügen), und klappen Sie ihn auf. Sie sollten Einträge für die beiden Aktionen (Starten und Stopp) sehen, die Ihr Dienst ausgeführt hat.
Bereinigen von Ressourcen
Wenn Sie die Windows-Dienst-App nicht länger benötigen, können Sie sie entfernen.
Öffnen Sie die Developer-Eingabeaufforderung für Visual Studio mit Administratoranmeldeinformationen.
Navigieren Sie im Fenster Developer-Eingabeaufforderung für Visual Studio zu dem Ordner, der die Ausgabe Ihres Projekts enthält.
Geben Sie folgenden Befehl ein:
installutil.exe /u MyNewService.exe
Wenn der Dienst erfolgreich deinstalliert wurde, meldet der Befehl, dass der Dienst erfolgreich entfernt wurde. Weitere Informationen finden Sie unter Vorgehensweise: Installieren und Deinstallieren von Diensten.
Nächste Schritte
Nach der Erstellung des Diensts haben Sie nun folgende Möglichkeiten:
Erstellen eines eigenständigen Setupprogramms, damit andere Personen Ihren Windows-Dienst installieren können. Verwenden Sie das WiX-Toolset, um einen Installer für einen Windows-Dienst zu erstellen. Weitere Ideen finden Sie unter Erstellen eines Installationspakets.
Sie können die Verwendung einer ServiceController-Komponente untersuchen, die es Ihnen ermöglicht, Befehle an den installierten Dienst zu senden.
Sie können einen Installer verwenden, um ein Ereignisprotokoll während der Installation anstatt während der Ausführung der Anwendung zu erstellen. Das Ereignisprotokoll wird vom Installer entfernt, wenn Sie die Anwendung deinstallieren. Weitere Informationen finden Sie unter EventLogInstaller.