0

I'm trying to make a Service using FileSystemWatcher to detect some changes in my C drive.

The following code is not triggering, and I'm not sure why.

FileSystemWatcher watcher;

    protected override void OnStart(string[] args)
    {
        trackFileSystemChanges();
        watcher.EnableRaisingEvents = true;
    }

The trackFileSystemChanges() method basically sets watcher to watch for changes in LastWrite and LastAccess time, the creation, deletion, or renaming of text files in the directory.

    [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
    public void trackFileSystemChanges()
    {
        watcher = new FileSystemWatcher();

        watcher.Path = @"C:\";
        Library.WriteErrorLog(watcher.Path);
        watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
        watcher.Filter = "*.*";

        watcher.Changed += new FileSystemEventHandler(OnChanged);
        watcher.Created += new FileSystemEventHandler(OnChanged);
        watcher.Deleted += new FileSystemEventHandler(OnChanged);
        watcher.Renamed += new RenamedEventHandler(OnRenamed);
    }

When txt files are changed or renamed, the log gets written to a file.

    private static void OnChanged(object source, FileSystemEventArgs e)
    {
        // Specify what is done when a file is changed, created, or deleted.
        Library.WriteErrorLog("File: " + e.FullPath + " " + e.ChangeType);
    }

    private static void OnRenamed(object source, RenamedEventArgs e)
    {
        // Specify what is done when a file is renamed.
        Library.WriteErrorLog("File: " + e.OldFullPath + "renamed to " + e.FullPath);
    }

There is no problem with the Library.WriteErrorLog method as I've tested it with other stuff. When the service is started, and when I tried editing/renaming some txt files within my C drive, nothing gets logged.

  • 1
    Did you try this in a console app first? – TheGeneral Jun 22 '18 at 03:44
  • Is the service running as a user with permission to the filesystem, like SYSTEM? – Josh Jun 22 '18 at 04:45
  • Be sure to check out _[The difference between the 'Local System' account and the 'Network Service' account?](https://stackoverflow.com/a/510225/585968)_ –  Jun 22 '18 at 04:47
  • @Josh If by _"SYSTEM"_ you mean `Local System` then a) it is not a _"user"_ and b) _"[Completely trusted account, more so than the administrator account. There is **nothing on a single box that this account cannot do**, and it has the right to access the network as the machine (this requires Active Directory and granting the machine account permissions to something)](https://stackoverflow.com/a/510225/585968)"_ –  Jun 22 '18 at 04:50
  • By the way `[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]` doesn't actually do anything with respect to elevating or ensuring your code runs at that CAS level, something needs to look for it first and grant it when the `AppDomain` is created. More than likely the FSW is performing an explicit CAS demand that will fault if the call chain is not satisfied. –  Jun 22 '18 at 04:59

2 Answers2

1

Adding to SengokuMedaru's answer, the FileSystemWatcher does not by default include child folders so if you:

watcher.Path = @"C:\";

...changes to C:\Users\User1\ConfidentialFiles would not be reported.

You have two choices.

  1. Specify the explicit root folder where you know files will be changing and have an interest in. i.e. watcher.Path = @"C:\Users\User1\ConfidentialFiles"; (Optionally set IncludeSubdirectories depending on your needs) or...

  2. Set IncludeSubdirectories to true.


Note however that setting IncludeSubdirectories to true with watcher.Path = @"c:\"; would not be advisable due to the huge amount of traffic you will encounter (and is at the mercy of being truncated too due to buffer limits)


MSDN:

Set IncludeSubdirectories to true when you want to watch for change notifications for files and directories contained within the directory specified through the Path property, and its subdirectories. Setting the IncludeSubdirectories property to false helps reduce the number of notifications sent to the internal buffer. For more information on filtering out unwanted notifications, see the NotifyFilter and InternalBufferSize properties. More...

0

I've found a solution, and that is to state explicitly the directory that I'm trying to find the file changes in. Otherwise for some reason, it won't work.

Eg:

 watcher.Path = @"C:\Users\User1\ConfidentialFiles";
  • but you had already set it to `C:`. How to explain it works for a subfolder but not the entire C drive? – kennyzx Jun 22 '18 at 05:18