The FileSystemWatcher project, shown in Figure 11.3, demonstrates how to set up a FileSystemWatcher component and how to process the events raised by the component. The FileSystemWatcher component is initialized when the Start Monitoring button is clicked. This button’s Click event handler prepares the FileSystemWatcher component to monitor changes in text files on the root of the C: drive. I’ve chosen the root folder because it’s easy to locate and it has very few files on most systems. You can create, edit, rename, and then delete a few text files in the root folder to test the application.
After setting the Path, Filter and NotifyFilter properties, the code sets the component’s EnableRaisingEvents property to True to start watching for changes. These changes will be signaled though the component’s events, which are programmed to print in the ListBox control at the bottom of the form the type of change detected and the name of the corresponding file. The type of change is reported to the event handler through the ChangeType member of the e argument. When a file is renamed, the program prints both the old and the new name.
The Start Monitoring button is a toggle. When clicked for the first time, its caption changes to Stop Monitoring; if you click it again, it will stop monitoring the file system.
The properties of the FileSystemWatcher component are set in the form’s Load event, which is shown in Listing 11.16.
Listing 11.16: Programming the FileSystemWatcher Component
Code language: PHP (php)
Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles MyBase.Load FileSystemWatcher1.IncludeSubdirectories = False FileSystemWatcher1.EnableRaisingEvents = False Dim filters() As String filters = [Enum].GetNames(GetType(IO.NotifyFilters)) Dim filter As String For Each filter In filters CheckedListBox1.Items.Add(filter) Next CheckedListBox1.SetItemChecked(1, True) CheckedListBox1.SetItemChecked(2, True) CheckedListBox1.SetItemChecked(3, True) End Sub
The code behind the button’s Click event handler (Listing 15.17) toggles the EnableRaisingEvents property and the button’s caption. When this property is set to True, the FileSystemWatcher component starts monitoring the changes in the file system.
Listing 11.17: Code of the Start Monitoring Button
Code language: PHP (php)
Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click If Button1.Text = "Start Monitoring" Then If txtPath.Text.Trim.Length = 0 Then MsgBox("Please select a folder to monitor for file changes") Exit Sub End If If txtFileTypes.Text.Trim.Length = 0 Then MsgBox("Please specify the file types to monitor") Exit Sub End If FileSystemWatcher1.Filter = txtFileTypes.Text.Trim FileSystemWatcher1.Path = txtPath.Text.Trim FileSystemWatcher1.NotifyFilter = _ IO.NotifyFilters.CreationTime Or IO.NotifyFilters.LastWrite Or _ IO.NotifyFilters.LastAccess Or IO.NotifyFilters.FileName FileSystemWatcher1.EnableRaisingEvents = True Button1.Text = "Stop Monitoring" Else FileSystemWatcher1.EnableRaisingEvents = False Button1.Text = "Start Monitoring" End If End Sub
Now you must program the handlers of the FileSystemWatcher component. You need not program all the events, only the ones you want to monitor. Because the Changed, Created, and Deleted event handlers have the same arguments, you can write a common handler for all three and a separate one for the Renamed event. Listing 11.18 details the event handlers of the sample applications.
Listing 11.18: Event Handlers of the FileSystemWatcher Component
Code language: CSS (css)
Private Sub FileSystemWatcher1_Changed(ByVal sender As Object, _ ByVal e As System.IO.FileSystemEventArgs) Handles _ FileSystemWatcher1.Changed, _ FileSystemWatcher1.Created, _ FileSystemWatcher1.Deleted ListBox1.Items.Add(e.ChangeType.ToString & vbTab & e.FullPath) End Sub Private Sub FileSystemWatcher1_Renamed(ByVal sender As Object, _ ByVal e As System.IO.RenamedEventArgs) Handles _ FileSystemWatcher1.Renamed ListBox1.Items.Add("RENAMED" & vbTab & e.OldFullPath & " TO " & e.FullPath) End Sub
If you want to handle the Error event, you must stop monitoring the file system momentarily, double the value of the InternalBufferSize property, and then enable the monitoring again, as shown in Listing 11.19.
Listing 11.19: Programming the FileSystemWatcher’s Error Event
Code language: PHP (php)
Private Sub FileSystemWatcher1_Error(ByVal sender As Object, _ ByVal e As System.IO.ErrorEventArgs) Handles _ FileSystemWatcher1.Error If FileSystemWatcher1.EnableRaisingEvents Then FileSystemWatcher1.EnableRaisingEvents = False FileSystemWatcher1.InternalBufferSize = 2 * _ FileSystemWatcher1.InternalBufferSize FileSystemWatcher1.EnableRaisingEvents = True End If End Sub
Some file operations might cause multiple events. The actions of moving and copying a file from one folder to another fire the Changed event several times. The same happens when you create a file with the desktop context menu because several attributes of the new file are set as soon as it’s created. To avoid multiple notifications, you should monitor for a few events only. A common use of the FileSystemWatcher component is to detect the creation of a new file in a special folder and act on it (such as when applications or users leave a file to a specific folder or when remote users upload a file to an FTP server). To detect the creation of new files, leave the NotifyFilter property to its default value and program the control’s Created event handler.