Служба Windows на локальном компьютере запущена, а затем остановлена ​​ошибка

105

Обычно я получаю такую ​​ошибку: (Служба «имя службы» на локальном компьютере была запущена, а затем остановлена. Некоторые службы останавливаются автоматически, если они не используются другими службами или программами), когда что-то не так с моим кодом, например, несуществующий пути к диску и т. д. Служба Windows не запускается.

У меня есть служба Windows, которая выполняет резервное копирование папки / файлов в место, если оно достигло предельного размера. Все подробности предоставляются XML-конфигурацией, которую служба Windows читает при запуске. У меня есть отдельные формы Windows, в которых есть кнопка, которая делает именно то, что делает при запуске моей службы Windows. Я использую свои формы Windows для отладки кода перед тем, как поместить его в свою службу Windows.

Когда я запускаю свои окна. Он делает то, что должен делать. Когда я поместил свой код в метод OnStart () службы Windows, появилась ошибка.

Вот мой код:

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

Я не знаю, что заставляет службу Windows не запускаться, симулятор формы Windows работал нормально. В чем проблема?

ОБНОВЛЕНИЕ: после многих испытаний я заметил, что при использовании только каталога папок (без файла) служба Windows не работает. Когда я заменил переменную fileWatch определенным файлом (включая его каталог), служба Windows запустилась. Когда я вернул его в папку, ничего не вышло. Я думаю, что расположение папок не работает в диспетчере файлов.

Когда я попытался создать новую службу Windows, которая следит за местоположением папки, она сработала .. Однако, когда я попробовал то же самое местоположение в исходной службе Windows, это не сработало! Я был наплевать! Кажется, что мне нужно создавать новую службу Windows и строить установщик каждый раз, когда я помещаю новый код / ​​функцию. Таким образом я могу отслеживать, где я получаю ошибку.

Blackator
источник

Ответы:

204

Если служба запускается и останавливается таким образом, это означает, что ваш код генерирует необработанное исключение. Это довольно сложно отладить, но есть несколько вариантов.

  1. Обратитесь к программе просмотра событий Windows . Обычно это можно сделать, перейдя в диспетчер компьютера / сервера и щелкнув « Просмотр событий» -> « Журналы Windows» -> « Приложение» . Здесь вы можете увидеть, что вызвало исключение, что может помочь, но вы не получите трассировку стека.
  2. Извлеките логику своей программы в проект класса библиотеки. Теперь создайте две разные версии программы: консольное приложение (для отладки) и службу Windows. (Это немного начальное усилие, но в долгосрочной перспективе избавит от лишних забот.)
  3. Добавьте больше блоков try / catch и ведение журнала в приложение, чтобы лучше понять, что происходит.
МакГарнагл
источник
11
Средство просмотра событий Windows показало полную трассировку стека, очень полезный инструмент.
Imam
37

Не уверен, что это будет полезно, но для отладки службы вы всегда можете использовать в методе OnStart следующее:

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

чем вы могли бы присоединить свою визуальную студию к процессу и иметь лучшие возможности отладки.

надеюсь, это было полезно, удачи

Эяль Х
источник
Это, безусловно, лучшее решение (по крайней мере, для меня). VS 2015 также отлично справляется с этим. Для меня появилось диалоговое окно подтверждения UAC для отладчика JIT, а затем я выбрал VS 2015 в качестве отладчика.
Смитти
9

Я нашел очень удобным преобразовать существующую службу Windows в консоль , просто изменив вашу программу следующим образом. С этим изменением вы можете запускать программу путем отладки в Visual Studio или запускать исполняемый файл в обычном режиме. Но он также будет работать как служба Windows. Я также написал об этом в блоге

program.cs

class Program
{
    static void Main()
    {
        var program = new YOUR_PROGRAM();
        if (Environment.UserInteractive)
        {
            program.Start();
        }
        else
        {
            ServiceBase.Run(new ServiceBase[]
            {
                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
    }
}
Бен Андерсон
источник
2

EventLog.Log должен быть установлен как «Приложение».

панини питке
источник
Я просто проголосовал за, так как это было для меня решением проблемы
Savage
1

Между тем, другая причина: случайно удаленный файл .config вызвал такое же сообщение об ошибке:

«Служба на локальном компьютере была запущена, а затем остановлена. Некоторые службы останавливаются автоматически ...»

Эмре Гулдоган
источник
0

Используйте таймер и отметьте событие, чтобы скопировать файлы.

При запуске службы запустите время и укажите интервал времени.

Таким образом, служба продолжает работать и копирует файлы ontick.

Надеюсь, это поможет.

Сетху
источник
0

Вы можете захотеть провести модульное тестирование инициализации, но поскольку он находится в OnStart методе, это практически невозможно. Я бы посоветовал вынести код инициализации в отдельный класс, чтобы его можно было протестировать или хотя бы повторно использовать в тестере форм.

Во-вторых, добавить ведение журнала (с помощью Log4Net или аналогичного) и добавить подробное ведение журнала, чтобы вы могли видеть подробности об ошибках времени выполнения. Примерами ошибок времени выполнения могут быть AccessViolationи т. Д., Особенно если ваша служба работает без достаточных прав для доступа к файлам конфигурации.

Куинтон Бернхардт
источник
0

Учетная запись, на которой запущена служба, могла не сопоставить диск D: (они зависят от пользователя). Попробуйте поделиться каталогом и используйте полный UNC-путь в своемbackupConfig .

Ваш watcherof type FileSystemWatcherявляется локальной переменной и выходит за рамки, когда OnStartметод выполнен. Вероятно, она вам понадобится как переменная экземпляра или класса.

Альф Кори Лефдаль
источник
0

Я столкнулся с той же проблемой. Моя служба загружает / получает XMLS и записывает ошибки в журнал событий.

Когда я зашел в журнал событий, я попытался его отфильтровать. Это подсказывает мне, что журнал событий был поврежден.

Я очистил журнал событий и все в порядке.

ПаносПлат
источник
0

В нашем случае в журналы событий Windows ничего не было добавлено, кроме журналов того, что проблемная служба была запущена, а затем остановлена.

Оказалось, что файл CONFIG службы был недействителен. Исправление неверного файла CONFIG устранило проблему.

рикитикитик
источник