web-dev-qa-db-de.com

Führen Sie einen Windows-Dienst als Konsolenanwendung aus

Ich möchte einen Windows-Dienst debuggen, aber es wird eine Fehlermeldung angezeigt 

Dienst kann nicht mit dem Befehl gestartet werden Zeile oder einen Debugger. Ein Windows-Dienst muss mit .__ installiert werden. installutil.exe und dann mit .__ gestartet. der Server-Explorer, Windows-Dienste Verwaltungstools oder der NET-Start Befehl.

Ich habe keine Ahnung von diesem Fehler .....

 enter image description here

28
pinki

Bevor ein Windows-Dienst ausgeführt werden kann, muss er zuerst mit installutil "installiert" werden. Z.B:

C:\installutil -i c:\path\to\project\debug\service.exe

Dann können Sie die Liste der Dienste öffnen, um sie zu starten. Z.B:

  1. Klicken Sie mit der rechten Maustaste auf "Arbeitsplatz".
  2. Klicken Sie auf "Verwalten".
  3. Öffnen Sie "Dienste und Anwendungen"
  4. Klicken Sie auf "Dienste".
  5. Finden Sie Ihren Dienst in der Liste und klicken Sie mit der rechten Maustaste darauf
  6. Klicken Sie auf "Start"

Nach dem Start können Sie in Visual Studio gehen, auf 'Debug' klicken und dann auf 'Zum Prozess hinzufügen' klicken.

Eine weitere Technik besteht darin, diese Zeile zu Ihrer OnStart () - Methode im Service hinzuzufügen:

System.Diagnostics.Debugger.Launch();

Wenn Sie dies tun, werden Sie aufgefordert, eine Instanz von Visual Studio auszuwählen, in der der Dienst debuggt werden soll.

35
Chris Wenham

Sie können den Startmodus der Assembly ändern, je nachdem, ob Sie sich im DEBUG-Modus (normalerweise in Visual Studio, aber nicht unbedingt) oder im RELEASE-Modus (wenn sie als Dienst in der Produktion ausgeführt wird) befinden:

Ändere das:

static class Program
{
    static void Main()
    {
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] 
        { 
            new MyService() 
        };
        ServiceBase.Run(ServicesToRun);
    }
}

dazu:

static class Program
{
    static void Main()
    {
        #if(!DEBUG)
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
            { 
                new MyService() 
            };
            ServiceBase.Run(ServicesToRun);
        #else
            MyService myServ = new MyService();
            myServ.Process();
            // here Process is my Service function
            // that will run when my service onstart is call
            // you need to call your own method or function name here instead of Process();
        #endif
    }
}

Die Technik stammt von diesem Artikel und der Autor des Artikels, Tejas Vaishnav. Ich habe die Codefragmente hierher kopiert, weil SO vollständige Antworten vorgezogen werden, anstatt Links, die möglicherweise etwas verschwinden.

14
Ofer Zelig

Um diesen Fehler zu vermeiden und den Dienst außerhalb des üblichen Dienstcontrollers ausführen zu lassen, können Sie das Flag Environment.UserInteractive überprüfen. Wenn es gesetzt ist, können Sie den Dienst mit der Ausgabe an die Konsole ausführen, anstatt den ServiceBase-Code ausführen zu lassen, der diesen Fehler zurückgibt.

Fügen Sie dies dem Start von Program.Main () vor dem Code hinzu, der ServiceBase zum Ausführen des Dienstes verwendet: 

        if (Environment.UserInteractive)
        {
            var service = new WindowsService();
            service.TestInConsole(args);
            return;
        }

Da die OnStart-Methode und die OnStop-Methode in Ihrem Dienst protected sind, müssen Sie dieser Klasse eine weitere Methode hinzufügen, die Sie von Main () aus ausführen können, und ruft diese Methoden für Sie auf, z.

    public void TestInConsole(string[] args)
    {
        Console.WriteLine($"Service starting...");
        this.OnStart(args);
        Console.WriteLine($"Service started. Press any key to stop.");
        Console.ReadKey();
        Console.WriteLine($"Service stopping...");
        this.OnStop();
        Console.WriteLine($"Service stopped. Closing in 5 seconds.");
        System.Threading.Thread.Sleep(5000);
    }

Stellen Sie abschließend sicher, dass die Ausgabe eine Konsolenanwendung in den Eigenschaften des Projekts ist. 

Sie können den Dienst jetzt wie jede andere ausführbare Datei ausführen und er wird als Konsole gestartet. Wenn Sie es von Visual Studio aus starten, wird der Debugger automatisch hinzugefügt. Wenn Sie es registrieren und als Dienst starten, wird es ordnungsgemäß als Dienst ohne Änderungen ausgeführt.

Der einzige Unterschied, den ich gefunden habe, besteht darin, dass der Code bei Ausführung als Konsolenanwendung nicht in das Ereignisprotokoll geschrieben wird. Möglicherweise möchten Sie auch alles ausgeben, was Sie normalerweise auch an der Konsole protokollieren würden. 

Diese Service-Debugging-Technik ist eine der unter docs.Microsoft.com .

2
Stephen Turner

Bitte überprüfen Sie, ob Sie sich im Modus "DEBUG" oder "RELEASE" befinden. Ich habe diese Fehlermeldung erhalten, als ich den Dienst im Modus "RELEASE" debuggen wollte. Als ich das auf "DEBUG" änderte, funktionierte alles gut.

Dies ist, nachdem Sie den Dienst ordnungsgemäß installiert haben, wie von anderen Personen vorgeschlagen.

1
Himanshu1983

Ein anderer Grund kann sein, dass sich die Lösungskonfiguration im Freigabemodus anstelle des Debugmodus enter image description here

enter image description here

0
makdu

Es gibt ein Nuget-Paket, um dieses Problem zu lösen: install-package WindowsService.Gui

 Image of the runner GUI

Was macht das Paket?

Es ist hilfreich, wenn Sie eine Play/Stop/Pause-Benutzeroberfläche erstellen, wenn ein Debugger ausgeführt wird. Außerdem kann der Windows-Dienst auch von der Windows Services-Umgebung installiert und ausgeführt werden. All dies mit einer Codezeile! Was ist Service Helper? Als jemand, der häufig Windows Services schreibt, kann es frustrierend sein, wenn man die Kopfschmerzen beim Debuggen von Services angeht. Häufig sind Tricks, Hacks und teilweise Workarounds erforderlich, um den gesamten Code zu testen. Für Windows Services-Entwickler gibt es keine Erfahrung mit "nur Hit F5".

Service Helper löst dieses Problem, indem eine Benutzeroberfläche aufgerufen wird, die angezeigt wird, wenn ein Debugger angefügt ist, der die Windows-Diensteumgebung (so genau wie möglich) simuliert.

Das github-Projekt ist hier: https://github.com/wolfen351/windows-service-gui

Wie benutzt man?

Die einfachste Möglichkeit, Windows Service Helper für Ihr Projekt zu erhalten, besteht darin, das NuGet-Paket ServiceProcess.Helpers im offiziellen NuGet-Feed zu verwenden.

Nehmen Sie einfach einige Änderungen an dem typischen Code in "Program.cs" für Ihre Anwendung vor:

using System.ServiceProcess;
using ServiceProcess.Helpers; //HERE

namespace DemoService
{
    static class Program
    {
    static void Main()
    {
        ServiceBase[] ServicesToRun;

        ServicesToRun = new ServiceBase[] 
            { 
                new Service1() 
            };

        //ServiceBase.Run(ServicesToRun);
        ServicesToRun.LoadServices(); //AND HERE
    }
    }
}

Offenlegung: Ich bin der Betreuer dieses Projekts

0
user230910