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.
Nope, filesystemwatchers run on their own thread.
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.
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()); } } }
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With