2 Stimmen

Windows-Dienst (c#) startet nicht.

Entschuldigung für mein Englisch, ich bin kein Muttersprachler.

Ich versuche, einen Windows-Dienst zu erstellen. Wenn ich versuche, ein VS-Template zu erstellen, zu installieren und auszuführen, erhalte ich keine Fehlermeldungen.

Ich habe meine WinForms-Anwendung in einen Dienst portiert, einen Installer erstellt, einige Datenquellen hinzugefügt, eine Referenz für den Webservice hinzugefügt, einige Klassen hinzugefügt, aber KEINEN Code zu OnStart() und OnStop() hinzugefügt. Mein Code baut richtig und ich kann den Dienst über den Dienst-Manager starten und stoppen.

Wenn ich jedoch etwas Code zur Dienstklasse hinzufüge (den ich nirgendwo aufrufe) und wenn ich keinen Code zu OnStart() und zu OnStop() hinzufüge, kann ich den Dienst nicht starten und der Fehler lautet "Der Dienst reagiert nicht auf die Steuerfunktionen". Im Ereignisprotokoll kann ich die Ausnahme sehen:

System.ArgumentOutOfRangeException
Stack:
 in System.String.InternalSubStringWithChecks(Int32, Int32, Boolean)
 in System.String.Substring(Int32, Int32)
 in UpdaterFIAS.FIASMainClass.getNameFile(System.String, System.String, System.String)
 in UpdaterFIAS.FIASMainClass..ctor()
 in UpdaterFIAS.Updater..ctor()
 in UpdaterFIAS.Program.Main()

Und hier sehe ich, dass meine Funktion getNameFile() eine Ausnahme wirft. Allerdings wird dies in meinem Code nicht aufgerufen, weil ich leere OnStart() habe. Wie kann ich also herausfinden, was schiefgelaufen ist, wenn das Ereignisprotokoll nichts schreibt (wenn es in der OnStart() ist)? Und ich kann keinen Debugger daran anhängen, weil er diese Ausnahme wirft.

Bearbeitung: Vergessen zu sagen, mein Code funktioniert korrekt, wenn ich Windows Forms verwende, aber hier rufe ich nichts in OnStart auf, das Projekt baut ohne Fehler, aber ich habe eine Ausnahme beim Starten des Dienstes.

BEARBEITUNG 2: Program.cs Code:

namespace UpdaterFIAS
{
    static class Program
    {
        /// 
        /// Der Hauptpunkt für die Anwendung.
        /// 
        static void Main()
        {
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
            { 
                new Updater() 
            };
            ServiceBase.Run(ServicesToRun);
        }
    }
}

Updater.cs Code:

namespace UpdaterFIAS
{
    public partial class Updater : ServiceBase
    {
        public Updater()
        {
            InitializeComponent();
            if (!System.Diagnostics.EventLog.SourceExists("MySource"))
            {
                System.Diagnostics.EventLog.CreateEventSource("MySource", "MyNewLog");
            }
            eventLog1.Source = "MySource";
            eventLog1.Log = "MyNewLog";
        }

        FIASMainClass mainFIAS = new FIASMainClass();

        protected override void OnStart(string[] args)
        {
            //timer1 = new System.Timers.Timer(5000);
            //timer1.Elapsed += timer1_Elapsed;
            //timer1.AutoReset = false;
            //timer1.Enabled = true;

            //ServiceStarterThread = new Thread(ServiceStarter);
            //ServiceStarterThread.Start();

            eventLog1.WriteEntry("In OnStart");
            //mainFIAS.Start();
        }

        protected override void OnStop()
        {
            //if (updater != null && (updater.ThreadState != System.Threading.ThreadState.Aborted && updater.ThreadState != System.Threading.ThreadState.Stopped)) updater.Abort();
            //if (log != null && (log.ThreadState != System.Threading.ThreadState.Aborted && log.ThreadState != System.Threading.ThreadState.Stopped)) log.Abort();

            //log.Abort();
            //timer1.Enabled = false;
            //timer1.Dispose();

            eventLog1.WriteEntry("In OnStop");
            //mainFIAS.Stop();
        }
    }
}

BEARBEITUNG 3: FIASMainClass.cs Code:

namespace UpdaterFIAS
{
    class FIASMainClass
    {
        public FIASMainClass()
        { }

        public void Start()
        {
            ServiceStarterThread = new Thread(ServiceStarter);
            ServiceStarterThread.Start();
        }

        public void Stop()
        {
            if (updater != null && (updater.ThreadState != System.Threading.ThreadState.Aborted && updater.ThreadState != System.Threading.ThreadState.Stopped)) updater.Abort();
            if (log != null && (log.ThreadState != System.Threading.ThreadState.Aborted && log.ThreadState != System.Threading.ThreadState.Stopped)) log.Abort();
        }

        private void ServiceStarter()
        {
        ...
        }
    ...
    ...
    ...
    }
}

0voto

Philip Pittle Punkte 10778

Aus Ihrem Stack-Trace ist der Einstiegspunkt Program.Main. Von dort aus wird ein neuer Updater erstellt und getNameFiles aufgerufen. Das wäre der richtige Ort zum Starten.

Was das Debuggen eines Windows-Dienstes betrifft. Sie haben recht, das ist tatsächlich schwer. Es gibt zwei Tricks, die ich kenne. Der erste ist im Main (oder OnStart) ein Thread.Sleep zu setzen, bevor Sie etwas tun. Auf diese Weise haben Sie Zeit, Ihren Debugger anzuhängen.

Der andere Trick besteht darin, wenn Ihr Visual Studio auf dem gleichen Rechner wie Ihr Dienst ist, in das Main (oder OnStart) diese Zeile hinzuzufügen: Debugger.Launch(). Dadurch wird der Dienst angewiesen, Visual Studio für eine Debugging-Sitzung zu suchen. Weitere Informationen finden Sie hier: Debugger.Launch() bei Windows-Diensten in Windows 8

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