Why doesn't FileSystemWatcher detect changes from Visual Studio?
Asked Answered
S

4

26

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.

Sarraceniaceous answered 25/3, 2009 at 8:37 Comment(5)
I deleted my response. I realized that you said you're editing the same file in notepad and the watcher sees it. So doesn't sound like a permissions issue.Sitarski
Which windows version and service pack do you use?Centripetal
@tanascius: Vista x64 SP1 - are there some issues I should be aware of?Sarraceniaceous
I added an answer, althought this is not your problemCentripetal
@tanascius: That's certainly something to be aware of if (when) I use my simple tool in older environments! Thank you for sharing.Sarraceniaceous
G
40

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());
        }
    }
}
Gaulin answered 25/3, 2009 at 10:57 Comment(1)
That was not what I expected at all, but now it makes perfect sense. I suspect there is less chance of corrupting files in case of a crash, by doing it this way. Thank you!Sarraceniaceous
E
5

Solved by specifying NotifyFilter property:

FileSystemWatcher w = new FileSystemWatcher();           
w.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite 
| NotifyFilters.CreationTime;
Enervated answered 18/5, 2016 at 10:58 Comment(1)
This set of filters actually caused me to miss the necessary events. I was listening for all four events (Changed, Created, Deleted, Renamed) as in @Treb's answer, but also using the NotifyFilter's you give here (along with a Filter property to filter to just one specific file.) I found that I did not get any events for the file (but I did get some Changed events for temp files if I removed Filter, watched the whole dir). If I remove the NotifyFilter, it seems like it gives you all events, then I do get a "Deleted" and "Renamed" event for my one file.Triform
C
4

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.

Centripetal answered 25/3, 2009 at 14:56 Comment(0)
A
0

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.

Aphrodisiac answered 6/5 at 20:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.