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
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
Code language: PHP (php)
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
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
Code language: PHP (php)
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
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
Code language: CSS (css)
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
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
Code language: PHP (php)
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.