C#Windows服务无法正常运行

时间:2011-02-03 10:38:29

标签: c# windows-services filesystemwatcher

我编写了一个Windows服务(使用Visual Studio 2010 Premium,C#,.NET 4)来监控文件夹。它所做的就是检测文件夹中的更改(添加的文件/文件夹,删除的内容等),并将检测结果写入文本文件。不是事件日志,只是普通的.txt文件。

现在,它安装得很好(我推测),它出现在计算机管理中,允许我运行它。它应该在文件中写入“Monitoring started” - 但事实并非如此。然后,当我尝试停止服务时,它会给我这个错误:

“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:

好的,有人注意到我没有关闭我的Streams。傻,傻我。现在,我在那之后运行了服务,并没有得到同样的错误,我得到了这个:

“本地计算机上的FileMonitoring服务已启动然后停止。某些服务会自动停止,因为其他服务或程序未使用它们。”

这似乎更简单但我仍然不知所措。有什么想法吗?

非常感谢!

3 个答案:

答案 0 :(得分:3)

您必须考虑的一件事(尽管我认为这不是您的问题)是对文件的并发访问。

为确保关闭流,最好将它们包装在using语句中。

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附加到它,你可以单步执行它。

希望有所帮助。

答案 1 :(得分:0)

可能日志文件仍然在以前的进程中被阻止。尝试删除它。如果可能的话,情况并非如此。

如果无法删除该文件,请尝试重新启动并尝试再次删除它。现在应该工作。

以后文件将不再被阻止,因为您关闭了流。但是你应该实现一个try-catch-finally,以便在错误发生之后关闭fileaccess。

答案 2 :(得分:0)

这一行:

sw.Close(); 

可能抛出一个ObjectDisposedException,因为你已经关闭了它的底层文件流,而它仍然有数据要刷新它。

未捕获的异常会使进程崩溃,您看到的错误是Windows SCM报告,它注意到了这一点。

编辑:另外,我认为您可能需要在编写条目之前寻找文件的末尾。这可能就是您没有看到Start事件消息的原因。

相关问题