3 Stimmen

Probleme beim Starten, Anhalten und Debuggen von Windows-Diensten

Ich habe einen Dienst, dessen Laufzeit ich nicht kenne, ich schätze etwa 7 Sekunden. Aus irgendeinem Grund funktioniert der Dienst nach dem ersten Lauf nicht mehr und ich kann ihn nicht debuggen. Im Dienstemanager wird ständig "Start" angezeigt, und im Fenster "Prozess anhängen" kann ich ihn nicht finden.

Wenn ich versuche, ihn zu stoppen, erscheint die Stopp-Schaltfläche nur für eine Sekunde. Selbst wenn ich sie drücke, erhalte ich die Fehlermeldung "Windows konnte den Dienst 'Splive auf dem lokalen Computer nicht beenden. Der Dienst hat keinen Fehler zurückgegeben.

Wie lässt sich dieses Problem am besten lösen?

static void Main(string[] args)
    {
        ServiceBase.Run(new Program());
        ServiceController service = new ServiceController();
        service.ServiceName = "SpLive";
        service.Start();
        //Sp objSportingbet = new Sp();
        //objSportingbet.getListingsFromSp();
    }
    public Program()
    {
        this.ServiceName = "SpLive";
    }
    protected override void OnStart(string[] args)
    {
        base.OnStart(args);
        objSportingbet.getListingsFromSp();
        timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed);
        timer1.Interval = 7000;
        timer1.Enabled = true;
        timer1.Start();
    }
    protected override void OnStop()
    {
        base.OnStop();
        timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed);
        timer1.Interval = 7000;
        timer1.Enabled = false;
        timer1.Start();
    }
    private void timer1_Elapsed(object sender, EventArgs e)
    {
        ServiceController service = new ServiceController();
        service.ServiceName = "Sp";
        if (service.Status == ServiceControllerStatus.Stopped)
        {
            service.Start();
        }
        if (service.Status == ServiceControllerStatus.Running)
        {
            service.Stop();
        }
        timer1.Stop();
    }

    private void InitializeComponent()
    {
        // 
        // Program
        // 
        this.CanPauseAndContinue = true;
        this.CanShutdown = true;

    }

5voto

Richard Punkte 103159

Konfigurieren Sie den Dienst so, dass er unter dem Debugger startet: http://support.microsoft.com/kb/824344 Beachten Sie den Abschnitt "Einen Dienst so konfigurieren, dass er mit dem angeschlossenen WinDbg-Debugger startet".

Hinzufügung (habe jetzt den fraglichen Code):

static void Main(string[] args)
{
   ServiceBase.Run(new Program());
   ServiceController service = new ServiceController();
   service.ServiceName = "SpLive";
   service.Start();

ServiceBase.Run(instance) kehrt erst zurück, wenn der Dienst heruntergefahren ist, so dass Sie den Dienst ausführen und dann, nachdem er heruntergefahren ist, den SCM bitten, den Dienst auszuführen das führt nur zu Verwirrung.

Dies und die Tatsache, dass ein Timer versucht, den Zustand (gestartet <-> gestoppt) des Dienstes umzukehren, lässt mich glauben, dass Sie über das zugrunde liegende Prozessmodell eines Windows-Dienstes nachdenken müssen:

Wenn nur ein Dienst von der Exe implementiert wird:

  1. Der Dienst wird gestartet (beim Systemstart, durch eine Benutzeranfrage, ...): Der SCM führt die registrierte Befehlszeile aus

  2. Main läuft, teilen Sie dem SCM (über ServiceBase.Run ) um welchen Dienst es sich handelt. Diese muss mit der in Schritt 1 verwendeten Registrierung übereinstimmen.

  3. Die Instanz, die an ServiceBase.Run hat seine OnStart genannt. Der Dienst sollte Aktivitäten starten, die er ausführen wird, und dann zurückkehren (d.h. asynchrone Operationen, neue Threads und der Thread-Pool sind OK; die Fortsetzung auf dem Thread, der die OnStart ist nicht).

  4. Wenn das Signal zum Abschalten eintrifft (egal von welcher Quelle) OnStop genannt wird. Dies sollte das Anhalten aller Aktivitäten auslösen, die OnStart gestartet (oder seitdem gestartet) und warten, bis sie aufhören und dann zurückkehren.

Der einzige Grund für einen Dienst, sich selbst anzuhalten, wäre, wenn etwas anderes (z. B. seine eigene Verwaltungs-API) ihn auslöst, aber es wäre besser, den SCM von der Benutzeroberfläche aus zu verwenden.

4voto

Maciej Punkte 7601

Idealerweise würden Sie die Debugging-Funktion Ihres Dienstes OnStart Methode, um zu sehen, was vor sich geht. Und es ist möglich:

protected override void OnStart(string[] args)
{
    #if DEBUG
    Debugger.Launch();
    #endif
    ...
}

Dies funktioniert auch, wenn der Dienst nicht als interaktiver Desktop gekennzeichnet ist.

1voto

Gerard ONeill Punkte 3528

Die OnStart und OnStop Handler haben ein festes Zeitlimit für die Bearbeitung. Ich weiß nicht, wie das Anhalten funktioniert (ob es wartet, bis ein Thread fertig ist ), aber für OnStart, in Ihrem Fall (ich weiß, es ist ein altes Thema ) würde ich den gesamten Anwendungscode in einen Timer-Callback verschieben und den Timer in der OnStart-Funktion einstellen. Ich habe meinen auf etwa 1 Minute eingestellt. Die OnStart-Funktion wird sofort beendet, was die Anforderungen der Dienstmanager erfüllt. Aber jetzt haben Sie einen Thread, der in etwa einer Minute starten wird, was Ihnen Zeit gibt, Ihren Prozess mit dem Debugger zu verbinden. Setzen Sie natürlich einen Haltepunkt bei der ersten Anweisung im OnStart-Timer-Callback.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X