Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FileSystemWatcher does not work with path set to drive root if on same drive as application

I'm using FileSystemWatcher to check for changes to .exe files anywhere on a drive.

FileSystemWatcher Watcher;

[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
public void Start() {
    Watcher = new FileSystemWatcher("C:") {
        NotifyFilter = NotifyFilters.Attributes | NotifyFilters.CreationTime | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Size | NotifyFilters.Security,
        Filter = "*.exe",
        IncludeSubdirectories = true
    };
    Watcher.Created += OnChanged; //Among other events
    Watcher.EnableRaisingEvents = true;
}

private void OnChanged(object source, FileSystemEventArgs e) {
    Debug.WriteLine(e.FullPath);
}

The issue is, if I have the watcher's path set to C: to check for files on the entire C: drive while also having my application being run anywhere on the C: drive (Eg. C:\Users\Name\Desktop\App.exe), the watcher doesn't fire any events.

If I instead set the path to C:\Users then the watcher will fire events - but this is of course limited to changes made to files under C:\Users which doesn't help if the file is in Program Files or such instead.

The same issue happens if I have the watcher checking the D: drive while my application is anywhere on the D: drive.

So it seems to not be possible to set the path to the root of the drive that the application is running on. What could be causing this?

like image 941
Pyon Avatar asked Dec 11 '25 19:12

Pyon


1 Answers

You need to pass @"C:\" to the constructor instead of "C:".

The path C: means "the current directory on the C: drive" whereas C:\ means "the root directory on the C: drive." You can see this for yourself by opening Command Prompt and running...

cd /D "%SystemRoot%"
dir %SystemDrive%\
dir %SystemDrive%

The second command (e.g. dir C:\) will show the contents of the root directory of the system drive, whereas the last command (e.g. dir C:) will display the contents of the current directory on the system drive, which is the system directory (e.g. C:\Windows). That's because it is a relative path but for a specific drive. From Naming Files, Paths, and Namespaces...

If a file name begins with only a disk designator but not the backslash after the colon, it is interpreted as a relative path to the current directory on the drive with the specified letter. Note that the current directory may or may not be the root directory depending on what it was set to during the most recent "change directory" operation on that disk. Examples of this format are as follows:

  • "C:tmp.txt" refers to a file named "tmp.txt" in the current directory on drive C.
  • "C:tempdir\tmp.txt" refers to a file in a subdirectory to the current directory on drive C.

Assuming when you start C:\Users\Name\Desktop\App.exe it has a working directory of C:\Users\Name\Desktop\, by passing "C:" to the FileSystemWatcher it ends up just watching the C:\Users\Name\Desktop\ directory, not the entire volume like you want. I tested your code in a quick .NET Core application and confirmed that when passing "C:" only changes made in the current (application) directory are reported, whereas when passing @"C:\" it does correctly monitor the entire volume.

like image 99
Lance U. Matthews Avatar answered Dec 14 '25 10:12

Lance U. Matthews



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!