Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't FileSystemWatcher detect changes from Visual Studio?

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.

like image 501
Haugholt Avatar asked Mar 25 '09 08:03

Haugholt


People also ask

Is FileSystemWatcher multithreaded?

Nope, filesystemwatchers run on their own thread.

What is FileSystemWatcher?

The FileSystemWatcher class in the System.IO namespace can be used to monitor changes to the file system. It watches a file or a directory in your system for changes and triggers events when changes occur. In order for the FileSystemWatcher to work, you should specify a directory that needs to be monitored.


3 Answers

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());         }     } } 
like image 93
Treb Avatar answered Sep 22 '22 05:09

Treb


Solved by specifying NotifyFilter property:

FileSystemWatcher w = new FileSystemWatcher();           
w.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite 
| NotifyFilters.CreationTime;
like image 25
Andrei Karcheuski Avatar answered Sep 22 '22 05:09

Andrei Karcheuski


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.

like image 23
tanascius Avatar answered Sep 22 '22 05:09

tanascius