SengokuMedaru
SengokuMedaru

Reputation: 3

C# FileSystemWatcher not triggering when used in a Service

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.

Upvotes: 0

Views: 568

Answers (2)

user585968
user585968

Reputation:

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...

Upvotes: 1

SengokuMedaru
SengokuMedaru

Reputation: 3

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";

Upvotes: 0

Related Questions