I have a pet project I'm working on where the FileSystemWatcher is vexing me.
Here's the initialization code:
for (var xx = 0; xx < _roots.Count; xx++)
{
var watcher = new FileSystemWatcher();
var root = _roots[xx];
watcher.Path = root;
// watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName;
watcher.Filter = "*.*";
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);
watcher.EnableRaisingEvents = true;
_rootWatchers.Add(watcher);
}
Let's say the root we're watching "c:\root" and there's a sub directory "c:\root\subdir" that contains a file called "file1.txt".
The watcher is up and running and I delete "file1.txt". When the handler is called and examine the values of FileSystemEventArgs
.
I expect for e.Name == "file1.txt"
and e.FullPath == "c:\\root\\subdir\\file1.txt
.
The actual values are "subdir"
and "c:\\root\\subdir"
.
I'm sure it's something simple I missed in the documentation somewhere.
You are correct, the issue you are facing is practically one of forgetting to set a property.
If you set watcher.IncludeSubdirectories = true;
, you'll get notified about the file deletion even in deeper levels.
In the default mode, the FileSystemWatcher
only records changes to the given directory. Sub-directories being modeled sort of directory entries similar to files, any additions/deletions inside them are just reported as changes directly to the sub-directories (you would see that if you checked the FileSystemEventArgs.ChangeType
property in the OnChanged
handler).
Even if you turn on sub-directories monitoring, you'll still get a change event (FileSystemEventArgs.ChangeType = WatcherChangeTypes.Changed
) for the subdir
directory as it is also modified when you delete a file inside it. That is in addition to the deletion event for the file.
My test code:
static void Main(string[] args)
{
var watcher = new FileSystemWatcher();
watcher.Path = @"C:\test_dir";
// watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName;
watcher.Filter = "*.*";
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);
watcher.IncludeSubdirectories = true;
watcher.EnableRaisingEvents = true;
while (true)
{
}
}
private static void OnRenamed(object sender, RenamedEventArgs e)
{
Console.WriteLine($"OnRenamed: {e.FullPath}, {e.OldFullPath}");
}
private static void OnChanged(object sender, FileSystemEventArgs e)
{
Console.WriteLine($"OnChanged: {e.ChangeType}, {e.Name}[{e.FullPath}]");
}