Question

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.

Was it helpful?

Solution

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());
        }
    }
}

OTHER TIPS

Solved by specifying NotifyFilter property:

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

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top