Служба Windows C # работает неправильно - PullRequest
1 голос
/ 03 февраля 2011

Я написал службу Windows (с использованием Visual Studio 2010 Premium, C #, .NET 4) для мониторинга папки.Все, что он делает, это обнаруживает, когда в папку вносятся изменения (добавляется файл / папка, что-то удаляется и т. Д.), И записывает обнаружение в текстовый файл.Не журнал событий, а обычный файл .txt.

Теперь он отлично устанавливается (я полагаю) и обнаруживается в Управлении компьютером и позволяет мне его запускать.Он должен написать «Мониторинг запущен» в файл - но это не так.Затем, когда я пытаюсь остановить службу, она выдает мне следующую ошибку:

"Windows не может остановить службу FileMonitoring на локальном компьютере. Служба не возвращает ошибку. Это может быть внутренняя Windowsошибка или внутренняя ошибка обслуживания. Если проблема не устранена, обратитесь к системному администратору. "

И не останавливается.Затем, когда я пытаюсь остановить его снова, я получаю эту ошибку:

«Windows не удалось остановить службу FileMonitoring на локальном компьютере. Ошибка 1061: в данный момент служба не может принимать управляющие сообщения».

А затем он останавливается.

Кто-нибудь знает, как решить эту проблему?Перед этим сервисом я просто создал простой сервис, который записывал в файл .txt «Запущен», когда сервис запущен, и «Остановлен», когда сервис остановлен, и он работал отлично.Все, что добавлено в это - это использование FileSystemWatcher.

Любая помощь будет принята с благодарностью, и я дам любую информацию / фрагменты кода, которые вам нужны, просто спросите.

Спасибо взаранее!

РЕДАКТИРОВАТЬ:

Вот код для вас:

protected override void OnStart(string[] args)
{
    watcher = new FileSystemWatcher();
    watcher.Path = @"C:\temp\services\Watched";

    watcher.Changed += new FileSystemEventHandler(LogFileSystemChanges);
    watcher.Created += new FileSystemEventHandler(LogFileSystemChanges);
    watcher.Deleted += new FileSystemEventHandler(LogFileSystemChanges);
    watcher.Renamed += new RenamedEventHandler(LogFileSystemRenaming);
    watcher.Error += new ErrorEventHandler(LogBufferError);
    watcher.EnableRaisingEvents = true;

    LogEntry("Monitoring Started.");
}

protected override void OnStop()
{
    watcher.EnableRaisingEvents = false;
    watcher.Dispose();

    LogEntry("Monitoring Stopped.");
}

void LogEntry(string message)
{
    counter++;

    FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
    StreamWriter sw = new StreamWriter(fs);

    sw.WriteLine(counter + ". " + message);

    fs.Close();
    sw.Close();
}

РЕДАКТИРОВАТЬ 2:

Хорошо, кто-то заметил тот факт, что я не закрыл свои потоки.Глупый, глупый я.После этого я запустил службу и не получил ту же ошибку, я получил такую:

"Служба FileMonitoring на локальном компьютере запускалась и затем останавливалась. Некоторые службы автоматически останавливаются, если онине используются другими службами или программами. "

Это кажется намного проще, но я все еще в растерянности.Есть идеи?

Большое спасибо!

Ответы [ 3 ]

3 голосов
/ 03 февраля 2011

Одной вещью, которую вы должны будете рассмотреть (хотя я не думаю, что это проблема в вашем случае), является одновременный доступ к файлу.

Чтобы обеспечить закрытие потоков, рекомендуется также обернуть их в операторы.

protected override void OnStart(string[] args)
{
    watcher = new FileSystemWatcher();
    watcher.Path = @"C:\temp\services\Watched";

    watcher.Changed += new FileSystemEventHandler(LogFileSystemChanges);
    watcher.Created += new FileSystemEventHandler(LogFileSystemChanges);
    watcher.Deleted += new FileSystemEventHandler(LogFileSystemChanges);
    watcher.Renamed += new RenamedEventHandler(LogFileSystemRenaming);
    watcher.Error += new ErrorEventHandler(LogBufferError);
    watcher.EnableRaisingEvents = true;

    LogEntry("Monitoring Started.");
}

protected override void OnStop()
{
    watcher.EnableRaisingEvents = false;
    watcher.Dispose();

    LogEntry("Monitoring Stopped.");
}

private object lockObject = new Object();

void LogEntry(string message)
{
    lock (lockObject)
    {
        counter++;

        using (StreamWriter sw = File.AppendText(path))
        {
            sw.WriteLine(counter + ". " + message);
        }
    }
}

Другой трюк, который вы можете использовать, - System.Diagnostics.Debugger.Break (); метод. Если вы добавите это в начало вашего сервиса, вам будет предложено подключить к нему Visual Studio, и вы сможете пройти через него.

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

0 голосов
/ 03 февраля 2011

Эта строка:

sw.Close(); 

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

Неполученное исключение приведет к сбою процесса, и вы видите ошибку, сообщающую Windows SCM о том, что она заметила это.файл перед записью записи.Возможно, именно поэтому вы не видите сообщений о событиях «Пуск».

0 голосов
/ 03 февраля 2011

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

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

в будущем файл больше не будет блокироваться, потому что вы закрыли поток. но вы должны реализовать try-catch-finally, чтобы доступ к файлу был окончательно закрыт после ошибки.

...