Pages

Wednesday, August 1, 2012

Using FileSystemWatcher

Undoubtedly one of the most interesting components in the .NET framework, and it's so useful that I was surprised to find out that it exists since the first version of the framework. I’m going to show simple and easy it is to work with.

I’ll adopt the description method first used by Felipe in here:

In my words:

FileSystemWatcher lets you monitor a given directory reporting every detected change, such as files and folders creations, renamings, exclusions, and changes. The most obvious use for it and probably what it’s more used for is automated file processing, for its reliability and speed.

In MSDN’s words:

Listens to the file system change notifications and raises events when a directory, or file in a directory, changes. Use FileSystemWatcher to watch for changes in a specified directory. You can watch for changes in files and subdirectories of the specified directory. You can create a component to watch files on a local computer, a network drive, or a remote computer.

A better look

It’s really a simple component, with few properties and events:

There are only two properties that would need some details:

Filter: A filter for files names and extensions. If you change it to *.txt, only changes made in .txt files will raise events.

NotifyFilter: Which kinds of changes will be used to determine a change. The default ones are enough for regular uses.

Its events are so simple that no further explanation is needed.

Demonstration

By now you should know what it does, and what it could be used for. I’m going to do a little demonstration on how to use it:

We’re going to use a simple form with a FileSystemWatcher, a TextBox, where we’re going to get the path to be watched from the user, and a button, to start monitoring.

To avoid having three methods that do the same thing, we’re going to use the same one to handle three of the events, Changed, Created and Deleted, since the three of them use the same signature. And an additional method for the Renamed event, as one of its arguments is not the same (to carry along the old name of the renamed file).

private void frmMain_Load(object sender, EventArgs e)
{
Watcher.Renamed += new RenamedEventHandler(Renamed);
Watcher.Deleted += new FileSystemEventHandler(Changed);
Watcher.Changed += new FileSystemEventHandler(Changed);
Watcher.Created += new FileSystemEventHandler(Changed);
}


Then we can set our two methods to handle these events, Renamed and Changed:

void Changed(object source, FileSystemEventArgs e)
{
string item = e.ChangeType + ": "+ e.Name;

lstChanges.Items.Add(item);
}

void Renamed(object sender, RenamedEventArgs e)
{
string item = "Renamed from: " + e.OldName + " to: " + e.Name;

lstChanges.Items.Add(item);
}

Now all we’ve got to do is to define what the Button is going to do:

private void btnStart_Click(object sender, EventArgs e)
{
try
{
Watcher.Path = txtPath.Text;
Watcher.EnableRaisingEvents = true;
}
catch (ArgumentException ex)
{
MessageBox.Show("This path does not exist: " + ex.Message);
}
}

Note: I don’t handle exceptions in any of these example codes to make it cleaner, but in this code above it’s really important, since it’s going to use the user input.

In case you’ve created the FileSystemWatcher programmatically, not by clicking the component on the Toolbox, then you have to take care of one more thing: a property of the watcher, SynchronizingObject. This is automatically taken care of by Visual Studio when you use it directly from the Toolbox, which is this demonstration’s case, but if you don’t, you just have to assign the form where you’re using to display the changes to the SynchronizingObject property like this:

Watcher.SynchronizingObject = this;

This code should be in the form, preferably right after the creation of the FileSystemWatcher instance.

Now we’re all set! Check below how this demonstration performed in a simple test:

Project

Felipe and I have been recently working on our first project in conjunction, and it’s entirely based on this component. I have to say that it’s getting really good, and we’re going to make the source code available, and then I’ll make a post about it in here.