Der Windows-Dienst auf dem lokalen Computer wurde gestartet und der Fehler wurde gestoppt

104

Normalerweise erhalte ich folgende Fehlermeldung: (Der Dienst "Dienstname" auf dem lokalen Computer wurde gestartet und dann gestoppt. Einige Dienste werden automatisch beendet, wenn sie nicht von anderen Diensten oder Programmen verwendet werden.) Wenn mit meinem Code etwas nicht stimmt, z. B. nicht vorhanden Laufwerkspfade usw. Der Windows-Dienst wird nicht gestartet.

Ich habe einen Windows-Dienst, der Ordner / Dateien an einem Speicherort sichert, wenn die Größenbeschränkung erreicht ist. Details werden alle von einer XML-Konfiguration bereitgestellt, die der Windows-Dienst beim Start liest. Ich habe ein separates Windows-Formular mit einer Schaltfläche, die genau das tut, was der Start meines Windows-Dienstes tut. Ich verwende meine Windows-Formulare zum Debuggen des Codes, bevor ich ihn in meinen Windows-Dienst einfüge.

Wenn ich meine Windows Forms starte. Es tut, was es zu tun vermutet. Als ich meinen Code in die OnStart () -Methode des Windows-Dienstes einfügte, wurde der Fehler angezeigt.

Hier ist mein Code:

protected override void OnStart(string[] args)
{

    private static string backupConfig = @"D:\LogBackupConfig\backupconfig.xml";
    private static string serviceStat = @"D:\LogBackupConfig\Status.txt";
    private static string fileFolderStat = @"D:\LogBackupConfig\FileFolderStat.txt";

    protected override void OnStart(string[] args)
    {
        if (File.Exists(backupConfig))
        {
            FileSystemWatcher watcher = new FileSystemWatcher();
            XmlTextReader reader = new XmlTextReader(backupConfig);

            XmlNodeType type;
            List<string> listFile = new List<string>();
            string fileWatch = "";

            //this loop is for reading XML elements and assigning to variables
            while (reader.Read())
            {
                type = reader.NodeType;
                if (type == XmlNodeType.Element)
                {
                    if (reader.Name == "File")
                    {
                        reader.Read();
                        fileWatch = reader.Value;
                    }
                    else if (reader.Name == "Folder")
                    {
                        reader.Read();
                        fileWatch = reader.Value;
                    }
                }
            }
            reader.Close();

            watcher.Path = fileWatch;
            watcher.Filter = "*.*";

            //this loop reads whether the service will watch a file/folder
            XmlTextReader reader1 = new XmlTextReader(backupConfig);
            while (reader1.Read())
            {
                type = reader1.NodeType;
                if (type == XmlNodeType.Element)
                {
                    if (reader1.Name == "File")
                    {
                        watcher.IncludeSubdirectories = false;
                        watcher.Changed += new FileSystemEventHandler(OnChangedFile);
                    }
                    else if (reader1.Name == "Folder")
                    {
                        watcher.IncludeSubdirectories = true;
                        watcher.Changed += new FileSystemEventHandler(OnChangedFolder);
                    }
                }
            }
            reader1.Close();

            watcher.EnableRaisingEvents = true;

        }
        else
        {
            StreamWriter sw = new StreamWriter(serviceStat, true);
            sw.WriteLine("File not found. Please start the Log Backup UI first.");
            sw.Close();
        }
    }

Ich weiß nicht, was den Windows-Dienst davon abhält, nicht zu starten. Der Windows Form Simulator hat einwandfrei funktioniert. Was scheint das Problem zu sein?

UPDATE: Nach vielen Versuchen habe ich festgestellt, dass der Windows-Dienst nicht funktioniert, wenn nur ein Ordnerverzeichnis (ohne Datei) verwendet wird. Als ich die Variable fileWatch durch eine bestimmte Datei (einschließlich ihres Verzeichnisses) ersetzte, wurde der Windows-Dienst gestartet. Als ich es wieder in einen Ordner geändert habe, hat es nicht funktioniert. Was ich denke ist, dass Ordnerpositionen in einem Filewatcher nicht funktionieren.

Als ich versuchte, einen neuen Windows-Dienst zu erstellen, der einen Ordnerspeicherort überwacht, funktionierte dies. Als ich jedoch denselben Speicherort in meinem ursprünglichen Windows-Dienst ausprobierte, funktionierte dies nicht! Ich war verrückt nach $ # * ed! Es scheint, dass ich jedes Mal, wenn ich einen neuen Code / eine neue Funktion platziere, einen neuen Windows-Dienst erstellen und das Installationsprogramm erstellen muss. Auf diese Weise kann ich verfolgen, wo ich einen Fehler erhalte.

Blackator
quelle

Antworten:

202

Wenn der Dienst so gestartet und gestoppt wird, bedeutet dies, dass Ihr Code eine nicht behandelte Ausnahme auslöst. Dies ist ziemlich schwierig zu debuggen, aber es gibt einige Optionen.

  1. Konsultieren Sie die Windows- Ereignisanzeige . Normalerweise können Sie dies erreichen, indem Sie zum Computer- / Server-Manager gehen und dann auf Ereignisanzeige -> Windows-Protokolle -> Anwendung klicken . Sie können hier sehen, was die Ausnahme ausgelöst hat, was möglicherweise hilfreich ist, aber Sie erhalten keine Stapelverfolgung.
  2. Extrahieren Sie Ihre Programmlogik in ein Bibliotheksklassenprojekt. Erstellen Sie nun zwei verschiedene Versionen des Programms: eine Konsolen-App (zum Debuggen) und den Windows-Dienst. (Dies ist ein wenig anfängliche Anstrengung, spart aber auf lange Sicht viel Angst.)
  3. Fügen Sie weitere Try / Catch-Blöcke hinzu und melden Sie sich bei der App an, um ein besseres Bild von den Vorgängen zu erhalten.
McGarnagle
quelle
10
Die Windows-Ereignisanzeige zeigte die vollständige Stapelverfolgung an, ein sehr hilfreiches Tool.
Talha Imam
37

Ich bin mir nicht sicher, ob dies hilfreich ist, aber zum Debuggen eines Dienstes können Sie in der OnStart-Methode immer Folgendes verwenden:

protected override void OnStart(string[] args)
{
     System.Diagnostics.Debugger.Launch();
     ...
}

als Sie Ihr Visual Studio an den Prozess anhängen und bessere Debug-Fähigkeiten haben könnten.

hoffe das war hilfreich, viel glück

Eyal H.
quelle
Dies ist bei weitem die beste Lösung (zumindest für mich). VS 2015 geht auch gut damit um. Für mich wurde ein UAC-Bestätigungsdialog für den JIT-Debugger angezeigt, und ich konnte dann VS 2015 als Debugger auswählen.
Smitty
9

Ich fand es sehr praktisch, Ihren vorhandenen Windows-Dienst in eine Konsole zu konvertieren, indem Sie einfach Ihr Programm wie folgt ändern. Mit dieser Änderung können Sie das Programm ausführen, indem Sie in Visual Studio debuggen oder die ausführbare Datei normal ausführen. Es funktioniert aber auch als Windows-Dienst. Ich habe auch einen Blog-Beitrag darüber gemacht

program.cs

class Program
{
    static void Main()
    {
        var program = new YOUR_PROGRAM();
        if (Environment.UserInteractive)
        {
            program.Start();
        }
        else
        {
            ServiceBase.Run(new ServiceBase[]
            {
                program
            });
        }
    }
}

YOUR_PROGRAM.cs

[RunInstallerAttribute(true)]
public class YOUR_PROGRAM : ServiceBase
{
    public YOUR_PROGRAM()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        Start();
    }

    protected override void OnStop()
    {
        //Stop Logic Here
    }

    public void Start()
    {
        //Start Logic here
    }
}
Ben Anderson
quelle
2

EventLog.Log sollte als "Anwendung" festgelegt werden.

Panini Pitke
quelle
Ich habe gerade gestimmt, da dies tatsächlich die Lösung für das Problem für mich war
Savage
1

In der Zwischenzeit ein weiterer Grund: Das versehentliche Löschen der .config- Datei verursachte die gleiche Fehlermeldung:

"Der Dienst auf dem lokalen Computer wurde gestartet und dann gestoppt. Einige Dienste werden automatisch beendet ..."

Emre Guldogan
quelle
0

Verwenden Sie Timer und kreuzen Sie das Ereignis an, um Ihre Dateien zu kopieren.

Starten Sie beim Starten des Dienstes die Uhrzeit und geben Sie das Zeitintervall an.

Der Dienst läuft also weiter und kopiert die Dateien ontick.

Hoffe es hilft.

Sethu
quelle
0

Möglicherweise möchten Sie die Initialisierung einem Komponententest unterziehen. Da dies jedoch in der OnStartMethode enthalten ist, ist dies nahezu unmöglich. Ich würde vorschlagen, den Initialisierungscode in eine separate Klasse zu verschieben, damit er getestet oder zumindest in einem Formulartester wiederverwendet werden kann.

Zweitens, um eine Protokollierung hinzuzufügen (mit Log4Net oder ähnlichem) und eine ausführliche Protokollierung hinzuzufügen, damit Sie Details zu Laufzeitfehlern sehen können. Beispiele für Laufzeitfehler sind AccessViolationusw., insbesondere wenn Ihr Dienst ohne ausreichende Berechtigungen für den Zugriff auf die Konfigurationsdateien ausgeführt wird.

Quinton Bernhardt
quelle
0

Das Konto, auf dem der Dienst ausgeführt wird, hat das D: -Laufwerk möglicherweise nicht zugeordnet (sie sind benutzerspezifisch). Versuchen Sie, das Verzeichnis freizugeben, und verwenden Sie den vollständigen UNC-Pfad in Ihrem backupConfig.

Ihr watcherTyp FileSystemWatcherist eine lokale Variable und liegt außerhalb des Gültigkeitsbereichs, wenn die OnStartMethode abgeschlossen ist. Sie benötigen es wahrscheinlich als Instanz oder Klassenvariable.

Alf Kåre Lefdal
quelle
0

Ich bin auf das gleiche Problem gestoßen. Mein Dienst lädt / empfängt XMLS und schreibt die Fehler in das Ereignisprotokoll.

Als ich zum Ereignisprotokoll ging, habe ich versucht, es zu filtern. Es fordert mich auf, dass das Ereignisprotokoll beschädigt wurde.

Ich habe das Ereignisprotokoll gelöscht und alles in Ordnung.

PanosPlat
quelle
0

In unserem Fall wurde in den Windows-Ereignisprotokollen nichts hinzugefügt, außer Protokollen, dass der problematische Dienst gestartet und dann gestoppt wurde.

Es stellt sich heraus, dass die CONFIG-Datei des Dienstes ungültig war. Das Korrigieren der ungültigen CONFIG-Datei hat das Problem behoben.

rikitikitik
quelle