How to: Use FileSystemWatcher to listen to local drives

I recently have done with some tasks on FileSystemWatcher class which is under System.IO namespace.  This class is not a new one, but looks very interesting that without any customized service from our side, it's capable of listening to your files system and will report to you regarding any changes happening to your local drives. Another reason why I am publishing this article is that I faced with a cross thread issue during execution. But I tackled that using delegate. This also will be fruitful like how we can call methods by crossing threads.

My tool will be monitoring the path @"E:\JAISH", which is one of my local folder. I need to track any changes happening inside it. So first, I configured

FileSystemWatcher fsw = new FileSystemWatcher();
fsw.Changed += new FileSystemEventHandler(Changed);
fsw.Created += new FileSystemEventHandler(FCreated);
fsw.Deleted += new FileSystemEventHandler(Deleted);
fsw.Renamed += new RenamedEventHandler(Renamed);
fsw.Path = @"E:\JAISH";
fsw.NotifyFilter = NotifyFilters.FileName |
                       NotifyFilters.Attributes |
                       NotifyFilters.LastAccess |
                       NotifyFilters.LastWrite |
                       NotifyFilters.Security |
                       NotifyFilters.Size |
                       NotifyFilters.CreationTime |
fsw.EnableRaisingEvents = true;

As you can see in above code, I registered event handlers for FileChanged, FileCreated, FileDeleted and FileRenamed events. I also set the path which needs to be monitored. NotifyFilter will determine whatever changes needs to be listened by FileSystemWatcher class.  Now look below for my code inside each event handlers. It is almost same.

DateTime dt = new DateTime();
dt = System.DateTime.UtcNow;
listItem = "File " + e.FullPath + " " + e.ChangeType.ToString() + " at " + dt.ToLocalTime().ToString();

I am just setting a string variable, listItem, with the values fetch inside event handler. Below I am describing what each value is meant.

e.FullPath - You will get the fill path of the file which raised this change event.
e.ChangeType - You will get the exact change type applied to the above mentioned file. i.e. Renamed, Deleted etc...
dt.ToLocalTime - You will get the current local time set in side your system.

Now I want to share some additional information to you all. This is a general one and not specific to FileSystemWatcher. Normally if you are in a thread, trying to access the resources inside another thread is not permissible. In this scenario you will get errors like ".....accessed from a thread other than the thread it was created on". If you really need to see this error, comment the below lines in AddFileEvents().

private void AddFileEvents()
    if (listBox1.InvokeRequired)
        myDelegate md = new myDelegate(AddFileEvents);
        this.Invoke(md, null);

Just run the attached code and rename any of the file under @"E:\JAISH". You will face this error. To overcome this scenario, I added those additional lines, which are commented in above section.

"InvokeRequired" property will decide that when calling any method of "listBox1", is it really needed to use "Invoke". Invoke method will be using to call a control method, if the location, may be another method,   calling the control method is running under a thread different to the thread under which controls created. So I made the thread cross using "Invoke". The 1st parameter of the "Invoke" is a delegate which is defined with the same prototype of local method AddFileEvents. Then we are firing the delegate i.e. through delegate we are firing AddFileEvents. These all will do only if "InvokeRequired" property returns true. Other wise it will just add information to listBox1.

I hope you got enough information of all logics and you may also like to download the attached code too. Replace the following line inside method SetFileWatcher() to a path value suitable to your local machine. 

fsw.Path = @"E:\JAISH";

Now run the downloaded solution and you should get a screen like below.


I created a new file like below in the path mentioned as fsw.Path. In my case the path is @"E:\JAISH"


Now I deleted the same file and checked the running application. You should get some thing like this.

The changes we made are displayed in the application. We never created any custom listeners but used the FileSystemWatcher class. Now your scope is to customize this tool with various options.