BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Input / Output
.NET 1.1+

Detecting File Changes with FileSystemWatcher

If you are developing a Windows Explorer-style application or integrating with a legacy or third-party system that can only provide information via files, you may need to monitor the files within a folder. The FileSystemWatcher class permits this.

Trapping the File Change Events

The FileSystemWatcher raises four events in response to changes in the monitored folder. These provide information for file and folder creation, modification, deletion and renaming. The first three of these are based on the FileSystemEventHandler delegate. This delegate includes a FileSystemEventArgs parameter that provides information relating to the path and name of the file or folder modified.

The Renamed event is based on the RenamedEventHandler delegate. This delegate provides a RenamedEventArgs object with information describing the activity that occurred. The RenamedEventArgs class is derived from FileSystemEventArgs but adds extra properties to hold the old name of the file or folder.

To attach to the four events in the sample application, add the following four lines to the end of the constructor:

_watcher.Changed += new FileSystemEventHandler(LogFileSystemChanges);
_watcher.Created += new FileSystemEventHandler(LogFileSystemChanges);
_watcher.Deleted += new FileSystemEventHandler(LogFileSystemChanges);
_watcher.Renamed += new RenamedEventHandler(LogFileSystemRenaming);

We now need to create two methods to process the notifications. The first method will handle the Changed, Created and Deleted events. In each case, the information from the event arguments will be logged in the list box. The list will display the time of the change, the name of the file affected and the type of change that occurred.

Add the following method to log the changes. The log text is created using the String.Format method with the {0:G} placeholder indicating that the current date and time will be formatted using the user's preferred short date format and long time format. The FullPath property returns the full path of the changed file. The ChangeType property returns a value from the WatcherChangeTypes enumeration that is automatically converted to a readable string by the Format method.

void LogFileSystemChanges(object sender, FileSystemEventArgs e)
{
    string log = string.Format("{0:G} | {1} | {2}", DateTime.Now, e.FullPath, e.ChangeType);
    ChangeLogList.Items.Add(log);
}

The second method to add will process the event raised when a file or folder is renamed. This method is similar to the previous one except that the change type is always "Renamed". We will log the old name and new path and name for the changed item.

Add the following method to log renaming:

void LogFileSystemRenaming(object sender, RenamedEventArgs e)
{
    string log = string.Format("{0:G} | {1} | Renamed from {2}", DateTime.Now
        , e.FullPath, e.OldName);
    ChangeLogList.Items.Add(log);
}

Enabling Monitoring

When a FileSystemWatcher object is created, the event raising capabilities are disabled. To enable the events, the EnableRaisingEvents property is set to true. Resetting the property to false at any time halts the raising of file change events. However, before the events are enabled, the path of the directory to monitor must be set in the Path property.

In the demonstration program we will link the EnableRaisingEvents property to the "MonitoringInput" checkbox. It will then be possible to switch the events on and off as required. Whenever event raising is enabled, the path to monitor will also be set. At the same time, we will enable or disable the textboxes so that changes can only be made when the events are disabled. Although this is not a requirement, it will make the sample program simpler to develop.

To enable the checkbox functionality, add the following method and link it to the checkbox's CheckChanged event:

private void MonitoringInput_CheckedChanged(object sender, EventArgs e)
{
    _watcher.Path = FolderInput.Text;
    _watcher.EnableRaisingEvents = MonitoringInput.Checked;

    FolderInput.Enabled = FileFilterInput.Enabled = !MonitoringInput.Checked;
}

NB: You would normally include validation to ensure that the monitored folder exists. To keep the example simple for this article, the validation code is not shown.

Testing the Program

You can now test the program. Once the running form is visible, change the contents of the textbox containing the path to monitor to a directory that exists on your hard disk. Use the MonitoringInput checkbox to enable the FileSystemWatcher and try creating, modifying, deleting and renaming files and folders within this directory to see the events being logged.

You may notice that some changes to files cause more than one event to be raised, depending upon the application used to edit the files. This is important to note as in some circumstances you would not want to handle the duplicated events. Note also that changes to the contents of a folder within the monitored directory cause Changed events to be raised. At the moment though, changes to subfolders at a deeper level do not raise events.

22 March 2008