我编写了一个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服务已启动然后停止。某些服务会自动停止,因为其他服务或程序未使用它们。”
这似乎更简单但我仍然不知所措。有什么想法吗?
非常感谢!
答案 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事件消息的原因。