Usługa Windows na komputerze lokalnym została uruchomiona, a następnie zatrzymała błąd

105

Zwykle pojawia się ten błąd: (Usługa „nazwa usługi” na komputerze lokalnym została uruchomiona, a następnie zatrzymana. Niektóre usługi zatrzymują się automatycznie, jeśli nie są używane przez inną usługę lub programy), gdy coś jest nie tak z moim kodem, np. Nieistniejący ścieżki dysków itp. Usługa systemu Windows nie uruchamia się.

Mam usługę systemu Windows, która tworzy kopie zapasowe folderów / plików w lokalizacji, jeśli osiągnęła limit rozmiaru. Szczegóły są dostarczane przez konfigurację XML, którą usługa Windows odczytuje przy starcie. Mam osobne formularze Windows, które mają przycisk, który robi dokładnie to, co robi moja usługa Windows na starcie. Używam formularzy systemu Windows do debugowania kodu przed umieszczeniem go w mojej usłudze systemu Windows.

Kiedy uruchamiam formularze w systemie Windows. Robi to, co powinien. Kiedy umieściłem kod w metodzie OnStart () usługi Windows, pojawił się błąd.

Oto mój kod:

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();
        }
    }

Nie wiem, co sprawia, że ​​usługa systemu Windows nie uruchamia się, symulator formularza systemu Windows działał dobrze. Co wydaje się być problemem?

AKTUALIZACJA: Po wielu próbach zauważyłem, że używając tylko katalogu folderów (bez pliku wyjściowego), usługa Windows nie działa. Kiedy zastąpiłem zmienną fileWatch określonym plikiem (łącznie z jego katalogiem), usługa systemu Windows została uruchomiona. Kiedy zmieniłem go z powrotem na lokalizację folderu, to nie zadziałało. Myślę, że lokalizacje folderów nie działają w programie do śledzenia plików.

Kiedy próbowałem utworzyć nową usługę systemu Windows, która obserwuje lokalizację folderu, zadziałało. Jednak gdy wypróbowałem tę samą lokalizację w mojej oryginalnej usłudze systemu Windows, nie zadziałało! Nie mogłem się doczekać $ # * ed! Wygląda na to, że muszę stworzyć nową usługę Windows i zbudować instalator za każdym razem, gdy umieszczam nowy kod / funkcję. W ten sposób mogę śledzić, gdzie pojawia się błąd.

Blackator
źródło

Odpowiedzi:

204

Jeśli usługa zostanie uruchomiona i zatrzymana w ten sposób, oznacza to, że kod zgłasza nieobsługiwany wyjątek. Jest to dość trudne do debugowania, ale jest kilka opcji.

  1. Zapoznaj się z przeglądarką zdarzeń systemu Windows . Zwykle możesz to zrobić, przechodząc do menedżera komputera / serwera, a następnie klikając Podgląd zdarzeń -> Dzienniki systemu Windows -> Aplikacja . Możesz zobaczyć, co spowodowało wyjątek tutaj, co może pomóc, ale nie dostajesz śladu stosu.
  2. Wyodrębnij logikę programu do projektu klasy bibliotecznej. Teraz utwórz dwie różne wersje programu: aplikację konsolową (do debugowania) i usługę Windows. (To trochę początkowego wysiłku, ale na dłuższą metę oszczędza wiele niepokoju).
  3. Dodaj więcej bloków try / catch i logowanie do aplikacji, aby uzyskać lepszy obraz tego, co się dzieje.
McGarnagle
źródło
10
Przeglądarka zdarzeń systemu Windows pokazała pełny ślad stosu, bardzo pomocne narzędzie.
Talha Imam
37

Nie jestem pewien, czy będzie to pomocne, ale w przypadku debugowania usługi zawsze możesz użyć następującego w metodzie OnStart:

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

niż możesz dołączyć swoje studio wizualne do procesu i mieć lepsze możliwości debugowania.

mam nadzieję, że to było pomocne, powodzenia

Eyal H.
źródło
To zdecydowanie najlepsze rozwiązanie (przynajmniej dla mnie). VS 2015 dobrze sobie z tym radzi. Dla mnie pojawiło się okno dialogowe potwierdzenia UAC dla debugera JIT, a następnie pozwól mi wybrać VS 2015 jako debuger.
Smitty
9

Zauważyłem, że bardzo przydatne jest przekonwertowanie istniejącej usługi systemu Windows na konsolę , po prostu zmieniając program w następujący sposób. Dzięki tej zmianie możesz uruchomić program, debugując w Visual Studio lub normalnie uruchamiając plik wykonywalny. Ale będzie również działać jako usługa systemu Windows. Napisałem również o tym wpis na blogu

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
źródło
2

EventLog.Log należy ustawić jako „Application”

panini pitke
źródło
Po prostu głosowałem za, ponieważ było to właściwie rozwiązanie problemu dla mnie
Savage
1

Tymczasem inny powód: przypadkowo usunięty plik .config spowodował pojawienie się tego samego komunikatu o błędzie:

„Usługa na komputerze lokalnym została uruchomiona, a następnie zatrzymana. Niektóre usługi zatrzymują się automatycznie ...”

Emre Guldogan
źródło
0

Użyj timera i zdarzenia tick, aby skopiować pliki.

Po uruchomieniu usługi uruchom czas i określ przedział czasu.

Usługa działa więc dalej i kopiuje pliki ontick.

Mam nadzieję, że to pomoże.

Sethu
źródło
0

Możesz chcieć przetestować jednostkowo inicjalizację - ale ponieważ znajduje się ona w OnStart metoda, jest to prawie niemożliwe. Sugerowałbym przeniesienie kodu inicjalizacyjnego do oddzielnej klasy, aby można go było przetestować lub przynajmniej ponownie wykorzystać w testerze formularzy.

Po drugie, aby dodać trochę rejestrowania (używając Log4Net lub podobnego) i dodać szczegółowe rejestrowanie, abyś mógł zobaczyć szczegółowe informacje o błędach czasu wykonania. Przykładami błędów w czasie wykonywania mogą być AccessViolationitp., Zwłaszcza jeśli usługa działa bez wystarczających uprawnień dostępu do plików konfiguracyjnych.

Quinton Bernhardt
źródło
0

Konto, na którym jest uruchomiona usługa, mogło nie mapować dysku D: -drive (są one specyficzne dla użytkownika). Spróbuj udostępnić katalog i użyj pełnej ścieżki UNC w swoimbackupConfig .

Twój watchertyp FileSystemWatcherjest zmienną lokalną i jest poza zakresem, gdy OnStartmetoda jest wykonywana. Prawdopodobnie potrzebujesz go jako zmiennej instancji lub klasy.

Alf Kåre Lefdal
źródło
0

Natknąłem się na ten sam problem. Moja usługa przesyła / odbiera XMLS i zapisuje błędy w dzienniku zdarzeń.

Kiedy przeszedłem do dziennika zdarzeń, próbowałem go przefiltrować. Monituje mnie, że dziennik zdarzeń jest uszkodzony.

Wyczyściłem dziennik zdarzeń i wszystko OK.

PanosPlat
źródło
0

W naszym przypadku w dziennikach zdarzeń systemu Windows nic nie zostało dodane poza dziennikami, że problematyczna usługa została uruchomiona, a następnie zatrzymana.

Okazuje się, że plik CONFIG usługi był nieprawidłowy. Poprawienie nieprawidłowego pliku CONFIG rozwiązało problem.

rikitikitik
źródło