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.

  1. 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.

  2. 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.

  3. 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.

  1. 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.

  2. Wählen Sie im Popupfenster Ja aus.

    Eingabeaufforderung zum Umbenennen

  3. Wählen Sie in der Registerkarte Design aus dem Kontextmenü Eigenschaften aus. Ändern Sie im Fenster Eigenschaften den Wert für ServiceName in MyNewService.

    Diensteigenschaften

  4. 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

  1. Öffnen Sie im Projektmappen-Explorer das Kontextmenü für MyNewService.cs oder MyNewService.vb, und wählen Sie dann Designer anzeigen aus.

  2. 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].

  3. Öffnen Sie im Projektmappen-Explorer das Kontextmenü für MyNewService.cs oder MyNewService.vb, und wählen Sie dann Code anzeigen aus.

  4. 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 den New()-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
    
  5. 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 eine Imports-Anweisung zur Datei MyNewService.vb hinzu:

    using System.Diagnostics;
    
    Imports System.Diagnostics
    
  6. 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
  1. Fügen Sie den System.Timers-Namespace hinzu, indem Sie die using-Anweisung in der Datei MyNewService.cs bzw. die Imports-Anweisung in der Datei MyNewService.vb verwenden:

    using System.Timers;
    
    Imports System.Timers
    
  2. 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()
    
  3. 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
    
  4. Fügen Sie der MyNewService-Klasse die OnTimer-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

  1. Fügen Sie den System.Runtime.InteropServices-Namespace hinzu, indem Sie die using-Anweisung in der Datei MyNewService.cs bzw. die Imports-Anweisung in der Datei MyNewService.vb verwenden:

    using System.Runtime.InteropServices;
    
    Imports System.Runtime.InteropServices
    
  2. 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 und dwCheckpoint der SERVICE_STATUS-Struktur, um zu bestimmen, wie lange bis zum Starten oder Herunterfahren eines Windows-Diensts gewartet werden muss. Wenn Ihre Methoden OnStart und OnStop eine lange Ausführungszeit haben, kann Ihr Dienst durch das erneute Aufrufen von SetServiceStatus mit einem erhöhten dwCheckPoint-Wert mehr Zeit anfordern.

  3. 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
    
  4. 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)
    
  5. 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)
    
  6. (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 die OnStop-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.

  1. Öffnen Sie im Projektmappen-Explorer das Kontextmenü für MyNewService.cs oder MyNewService.vb, und wählen Sie dann Designer anzeigen aus.

  2. 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.

  3. 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.

  4. Vergewissern Sie sich im Fenster Eigenschaften, dass die ServiceName-Eigenschaft auf MyNewService festgelegt ist.

  5. 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.

    Dienstbeschreibung im Fenster „Dienste“

  6. 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).

  7. Legen Sie die StartType-Eigenschaft über die Dropdownliste auf Automatic fest.

  8. Wenn Sie diesen Vorgang abgeschlossen haben, sollte das Eigenschaften-Fenster der folgenden Abbildung entsprechen:

    Eigenschaften für einen Windows-Dienst-Installer

  9. 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

  1. 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
    
  2. Ä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.

  3. 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

  1. Wählen Sie im Projektmappen-Explorer aus dem Kontextmenü des MyNewService-Projekts die Option Eigenschaften aus.

    Die Eigenschaftenseiten für Ihr Projekt werden angezeigt.

  2. 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.

  3. 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.

  1. Öffnen Sie die Developer-Eingabeaufforderung für Visual Studio mit Administratoranmeldeinformationen.

  2. 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).

  3. 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 als public definiert.

Weitere Informationen finden Sie unter Vorgehensweise: Installieren und Deinstallieren von Diensten.

Starten und Ausführen des Diensts

  1. Ö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.

    MyNewService im Fenster

  2. Der Dienst wird gestartet, wenn Sie im Kontextmenü des Diensts Starten auswählen.

  3. Der Dienst wird angehalten, wenn Sie im Kontextmenü des Diensts Stopp auswählen.

  4. (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

  1. Ö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.

  2. Klappen Sie in der EreignisanzeigeAnwendungs- und Dienstprotokolle auf.

  3. 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.

    Verwenden der Ereignisanzeige zum Anzeigen von Einträgen im Ereignisprotokoll

Bereinigen von Ressourcen

Wenn Sie die Windows-Dienst-App nicht länger benötigen, können Sie sie entfernen.

  1. Öffnen Sie die Developer-Eingabeaufforderung für Visual Studio mit Administratoranmeldeinformationen.

  2. Navigieren Sie im Fenster Developer-Eingabeaufforderung für Visual Studio zu dem Ordner, der die Ausgabe Ihres Projekts enthält.

  3. 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.

Siehe auch