Monday 15 November 2010

Using FileSystemWatcher to monitor multiple directories

In a previous example I have showed how to use ‘FileSystemWatcher’ class to monitor a directory. But there are times that we need to monitor multiple directories and if any changes are available, invoke a given method.

We can do that by using this method. First create a class. We’ll call this class ‘Watcher’

   1: public class Watcher
   2:     {
   3:  
   4:         public string Directory { get; set; }
   5:         public string  Filter { get; set; }
   6:  
   7:  
   8:         private Delegate _changeMethod;
   9:  
  10:         public Delegate ChangeMethod
  11:         {
  12:             get { return _changeMethod; }
  13:             set { _changeMethod = value; }
  14:         }
  15:         
  16:         FileSystemWatcher fileSystemWatcher = new FileSystemWatcher();
  17:  
  18:         public Watcher(string directory, string filter, Delegate invokeMethod)
  19:         {
  20:             this._changeMethod = invokeMethod;
  21:             this.Directory = directory;
  22:             this.Filter = Filter;
  23:         }
  24:  
  25:  
  26:         public void StartWatch()
  27:         {
  28:             
  29:             
  30:             fileSystemWatcher.Filter = this.Filter;
  31:             fileSystemWatcher.Path = this.Directory;
  32:             fileSystemWatcher.EnableRaisingEvents = true;
  33:  
  34:             fileSystemWatcher.Changed += new FileSystemEventHandler(fileSystemWatcher_Changed);
  35:         }
  36:  
  37:         void fileSystemWatcher_Changed(object sender, FileSystemEventArgs e)
  38:         {
  39:             if (_changeMethod != null)
  40:             {
  41:                 _changeMethod.DynamicInvoke(sender, e);
  42:             }
  43:         }
  44:     }

And we can use it to monitor multiple directories as shown below (for this example I have used a console application and I am only considering the change event):



   1: class Program
   2:     {
   3:         delegate void invokeMethodDelegate(object sender, FileSystemEventArgs e);
   4:  
   5:         static void Main(string[] args)
   6:         {
   7:             
   8:             invokeMethodDelegate mymethod = new invokeMethodDelegate(InvokeMethod);
   9:             Watcher w1 = new Watcher(@"C:\Directory1", "*.*", mymethod);
  10:             w1.StartWatch();
  11:  
  12:             Watcher w2 = new Watcher(@"D:\Directory2", "*.*", mymethod);
  13:             w2.StartWatch();
  14:  
  15:             string zRetVal = Console.ReadLine();
  16:  
  17:            
  18:         }
  19:  
  20:         static  void InvokeMethod(object sender, FileSystemEventArgs e)
  21:         {
  22:             Console.WriteLine("Change in file {0}", e.FullPath);
  23:         }
  24:     }

5 comments:

  1. You might also want to consider making it more generic by utilizing a collection of "Watcher" objects. For example, it could read a config file for various settings, and monitor as many separate directories as there are entries in the config file. Then, turn it into a windows service application and it can run continuously.
    --Just a thought.
    bob.oberst@prodigy.net

    ReplyDelete
  2. Dear Manjuke,

    Thank you for this brilliant tutorial. Only one thing i would like to point out. To ensure thread safety, especially in wpf applications where you want to sometimes fill a control not in the same thread, it's safer to use
    Application.Current.Dispatcher.Invoke(() => _changeMethod.DynamicInvoke(sender, e));

    This stopped my errors.

    Thank you!

    ReplyDelete
  3. Dear Manjuke,

    thanks a lot for this tutorial. I applied it successfully to check various directories but I can not access a litview in my main form to display the filename.

    Do you have an idea ?

    ReplyDelete
    Replies
    1. Could you please share your code ? Or perhaps mail me.. I'll check what's wrong..

      Delete