为什么 FileSystemWatcher 检测不到 Visual Studio 中的更改?

问题描述 投票:0回答:4

我制作了一个小型应用程序,可以响应文件夹中文件的更改。但是当我在 Visual Studio 2008 中编辑该文件时,它从未检测到任何内容。如果我在记事本中编辑文件,一切都会按预期进行。

Visual Studio 当然会在某个时刻保存文件,但当我关闭工作室时,观察器甚至不会触发。你知道我在这里缺少什么吗?

此示例代码(C#)应该可以说明问题:

FileSystemWatcher fileSystemWatcher = new FileSystemWatcher("C:\Test", "*.cs");
WaitForChangedResult changed = fileSystemWatcher.WaitForChanged(WatcherChangeTypes.All);
Console.Out.WriteLine(changed.Name);

我发现 Ayende 的一篇博客文章描述了同样的问题,但不幸的是没有解决方案。

c# visual-studio-2008 filesystemwatcher
4个回答
39
投票
这真是令人难以置信...当您尝试下面的示例程序并在 VS 中更改文件时,您会注意到输出窗口中出现两行:

已删除

更名了

因此 Visual Studio 永远不会

更改现有文件,它将内容保存到具有临时名称的新文件中,然后删除原始文件并将新文件重命名为旧名称。

实际上,这是一个很好的做法,因为如果您按照通常的方式执行此操作(仅写入更改的文件,这将导致

Changed

 事件被触发),则可能会在写入过程完成之前调用事件处理程序。如果事件处理程序处理文件内容,这可能会导致问题,因为它会处理不完整的文件。

换句话说:

这不是一个错误,而是一个功能;-)

static class Program { [STAThread] static void Main() { FileSystemWatcher FSW = new FileSystemWatcher("c:\\", "*.cs"); FswHandler Handler = new FswHandler(); FSW.Changed += Handler.OnEvent; FSW.Created += Handler.OnEvent; FSW.Deleted += Handler.OnEvent; FSW.Renamed += Handler.OnEvent; FSW.EnableRaisingEvents = true; System.Threading.Thread.Sleep(555000); // change the file manually to see which events are fired FSW.EnableRaisingEvents = false; } } public class FswHandler { public void OnEvent(Object source, FileSystemEventArgs Args) { Console.Out.WriteLine(Args.ChangeType.ToString()); } } }
    

5
投票
通过指定NotifyFilter属性解决:

FileSystemWatcher w = new FileSystemWatcher(); w.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.CreationTime;
    

4
投票
只是为了记录这种可能性......

来自

msdn

如果多个 FileSystemWatcher 对象在 Service Pack 1 之前的 Windows XP 或 Windows 2000 SP2 或更早版本中监视同一 UNC 路径,则只有其中一个对象会引发事件。在运行 Windows XP SP1 及更高版本、Windows 2000 SP3 或更高版本或 Windows Server 2003 的计算机上,所有 FileSystemWatcher 对象都会引发相应的事件。

所以我的想法是,无论出于何种原因,Visual Studio 在文件上保留自己的 FileSystemWatcher ...但是您没有 UNC 路径,也没有提到的操作系统。


0
投票
删除NotifyFilter属性设置,订阅所有这些。要修复事件未触发的原因,请尝试在实例化 filewatchersystem 后立即使用 filewatcher.BeginInit() 方法。在最后一条语句之后,添加 filewatcher.EndInit()。让我知道这是否适合您。

© www.soinside.com 2019 - 2024. All rights reserved.