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

发布于 2024-07-16 14:35:14 字数 600 浏览 7 评论 0原文

我制作了一个小型应用程序,可以响应文件夹中文件的更改。 但是当我在 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 描述了同样的问题,但不幸的是没有解决方案。

I have made a tiny application that responds to changes to files in a folder. But when I edit the file in Visual Studio 2008, it never detects anything. If I edit the file in Notepad instead, everything works as expected.

Surely Visual Studio saves the file at some point, but the watcher does not even trigger when I close the studio. Do you have any idea what I'm missing here?

This sample code (C#) should illustrate the problem:

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

I found a blog post by Ayende that describes the same problem, but unfortunately no solution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

风苍溪 2024-07-23 14:35:14

这真是令人难以置信...当您尝试下面的示例程序并在 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());
        }
    }
}

This was really mind boggling... when you try my example program below and change the file in VS, you will notice two lines in your output window:

Deleted

Renamed

So Visual Studio does never change an existing file, it saves the constents to a new file with a temporary name, then deletes the original file and renames the new file to the old name.

Actually, this is a good practice, because if you do it the usual way (just writing the changed file, which would cause the Changed event to be fired), the event handler may be called before the writing process is complete. If the event handler processes the file contents, this may cause problems because it would process an incomplete file.

In other words: It's not a bug, it's a feature ;-)

    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());
        }
    }
}
蓝眼泪 2024-07-23 14:35:14

通过指定 NotifyFilter 属性解决:

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

Solved by specifying NotifyFilter property:

FileSystemWatcher w = new FileSystemWatcher();           
w.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite 
| NotifyFilters.CreationTime;
一杯敬自由 2024-07-23 14:35:14

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

来自 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 路径,也没有提到的操作系统。

Just to document this possibility ...

From msdn:

If multiple FileSystemWatcher objects are watching the same UNC path in Windows XP prior to Service Pack 1, or Windows 2000 SP2 or earlier, then only one of the objects will raise an event. On machines running Windows XP SP1 and newer, Windows 2000 SP3 or newer or Windows Server 2003, all FileSystemWatcher objects will raise the appropriate events.

So my idea was that Visual Studio holds its own FileSystemWatcher on a file for whatever reason ... however you have no UNC paths and no mentioned OS.

土豪我们做朋友吧 2024-07-23 14:35:14

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

Removing the NotifyFilter property setting, subscribes to all of them. To fix why events are not firing, try using the filewatcher.BeginInit() method just after the instantiation of the filewatchersystem. After your very last statement, add filewatcher.EndInit(). Let me know if that works for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文