Search code examples
c#filesystemwatcher

How to write FileSystemWatcher without triggering an infinite loop


How do I write a file in C# to a folder path that is watched by FileSystemWatcher?

My fileSystemWatcher settings are as follows:

public FileSystemWatcher CreateAndExecute(string path)
{
    Console.WriteLine("Watching " + path);

    //Create new watcher
    FileSystemWatcher fileSystemWatcher = new FileSystemWatcher();

    fileSystemWatcher.Path = path;
    fileSystemWatcher.IncludeSubdirectories = false;
    fileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite | 
    NotifyFilters.FileName | NotifyFilters.DirectoryName;

    fileSystemWatcher.Filter = "*.txt";
    fileSystemWatcher.Changed += new FileSystemEventHandler(OnChange);

    fileSystemWatcher.InternalBufferSize = 32768;

    //Execute
    fileSystemWatcher.EnableRaisingEvents = true;
}

private void OnChange(object source, FileSystemEventArgs e)
{
    //Replace modified file with original copy
}

I want to replace a modified file's contents with a back up copy from a database whenever an unauthorized write (out of the program) happens to the file.

However, when i write using File.WriteAllText() to the modified file, it triggers a Change event by the FileSystemWatcher as the action is registered as a write again.

This causes the program to run in an endless loop of overwriting the file it has just wrote.

How can I replace the modified file with the backup copy, without triggering another event to write by FileSystemWatcher?


Solution

  • Apart from the fact that you can probably solve the problem in a better/different way by using the OS file security f.e., you have some options:

    • Temporarily disable the watcher, in which case you can loose events in case of a brute force attack, which might not be what you want.
    • Keep a list with files you've rewritten and ignore one change for files on the list and remove it from the list afterwards -> can also be abused if the malicious program knows this
    • Store a SHA1 or SHA256 (or other hash) of the file content and only replace the file if the hash is different -> probably the best approach for this problem