Welcome to my article. Today, I would like to talk about using the FileSystemWatcher in .NET.
What Is FileSystemWatcher?
As the name implies, it watches the system for files. To put it better: It watches a folder for any changes. These changes could be things like file deletion, file renaming, changing the properties of a file, and so on.
Let’s do a small practical example!
Open Visual Studio 2019 and create either a new C# or VB.NET Windows Forms application. Once your form has loaded, design it to resemble Figure 1.
It contains the following controls:
- A large ListBox
- Two textboxes with their Text properties set
- Seven CheckBoxes
Name them anything you like, but keep in mind that my names may differ from yours.
Figure 1: Design
Code
Add the following namespaces to your code.
C#
using System.IO;
VB.NET
Imports System.IO
Create the FileSystemWatcher object.
C#
private FileSystemWatcher fsWatch;
VB.NET
Private fsWatch As FileSystemWatcher
Set the properties for the FileSystemWatcher.
C#
public Form1() { InitializeComponent(); fsWatch = new FileSystemWatcher(); fsWatch.SynchronizingObject = this; fsWatch.Changed += new FileSystemEventHandler(LogFile); fsWatch.Created += new FileSystemEventHandler(LogFile); fsWatch.Deleted += new FileSystemEventHandler(LogFile); fsWatch.Renamed += new RenamedEventHandler(LogRename); }
VB.NET
Public Sub New() InitializeComponent() fsWatch = New FileSystemWatcher() fsWatch.SynchronizingObject = Me AddHandler fsWatch.Changed, New FileSystemEventHandler(AddressOf LogFile) AddHandler fsWatch.Created, New FileSystemEventHandler(AddressOf LogFile) AddHandler fsWatch.Deleted, New FileSystemEventHandler(AddressOf LogFile) AddHandler fsWatch.Renamed, New RenamedEventHandler(AddressOf LogRename) End Sub
Here, you set the SynchronizingObject to the current form. This allows the watcher to keep watching while the form is open. You then create four event handlers for each possible file change. Let’s add them now.
C#
void LogRename(object sender, RenamedEventArgs e) { lstLog.Items.Add(string.Format("{0:G} | {1} | Renamed from {2}", DateTime.Now, e.FullPath, e.OldName)) } void LogFile(object sender, FileSystemEventArgs e) { lstLog.Items.Add(string.Format("{0:G} | {1} | {2}", DateTime.Now, e.FullPath, e.ChangeType)); }
VB.NET
Private Sub LogRename(ByVal sender As Object, ByVal e As _ RenamedEventArgs) lstLog.Items.Add(String.Format("{0:G} | {1} | _ Renamed from {2}", DateTime.Now, e.FullPath, e.OldName)) End Sub Private Sub LogFile(ByVal sender As Object, ByVal e _ As FileSystemEventArgs) lstLog.Items.Add(String.Format("{0:G} | {1} | {2}", _ DateTime.Now, e.FullPath, e.ChangeType)) End Sub
When a file’s properties changes or gets renamed or moved, these events will fire. All they do is to simply log the current date and time along with the old and new names (if renamed), and the specific changed that has occurred.
Now, let’s add the final event to control which properties we’d like to track.
C#
private void chkMonitor_CheckedChanged(object sender, EventArgs e) { string strFolder = txtFolder.Text; bool blnExists = Directory.Exists(strFolder); if (blnExists) { fsWatch.Path = strFolder; fsWatch.Filter = FileFilterInput.Text; fsWatch.IncludeSubdirectories = chkSubFolders.Checked; NotifyFilters notificationFilters = new NotifyFilters(); if (chkAttributes.Checked) notificationFilters = notificationFilters | NotifyFilters.Attributes; if (chkCreationTime.Checked) notificationFilters = notificationFilters | NotifyFilters.CreationTime; if (chkFileName.Checked) notificationFilters = notificationFilters | NotifyFilters.FileName; if (chkLastWrite.Checked) notificationFilters = notificationFilters | NotifyFilters.LastWrite; if (chkSize.Checked) notificationFilters = notificationFilters | NotifyFilters.Size; fsWatch.NotifyFilter = notificationFilters; fsWatch.EnableRaisingEvents = chkMonitor.Checked; } else if (chkMonitor.Checked) { MessageBox.Show("Invalid Folder.", "Invalid Folder", MessageBoxButtons.OK, MessageBoxIcon.Error); chkMonitor.Checked = false; } }
VB.NET
Private Sub chkMonitor_CheckedChanged(ByVal sender As Object, _ ByVal e As EventArgs) Handles chkMonitor.CheckedChanged Dim strFolder As String = txtFolder.Text Dim blnExists As Boolean = Directory.Exists(strFolder) If blnExists Then fsWatch.Path = strFolder fsWatch.Filter = FileFilterInput.Text fsWatch.IncludeSubdirectories = chkSubFolders.Checked Dim notificationFilters As NotifyFilters = New _ NotifyFilters() If chkAttributes.Checked Then notificationFilters = _ notificationFilters Or NotifyFilters.Attributes If chkCreationTime.Checked Then notificationFilters = _ notificationFilters Or NotifyFilters.CreationTime If chkFileName.Checked Then notificationFilters = _ notificationFilters Or NotifyFilters.FileName If chkLastWrite.Checked Then notificationFilters = _ notificationFilters Or NotifyFilters.LastWrite If chkSize.Checked Then notificationFilters = _ notificationFilters Or NotifyFilters.Size fsWatch.NotifyFilter = notificationFilters fsWatch.EnableRaisingEvents = chkMonitor.Checked ElseIf chkMonitor.Checked Then MessageBox.Show("Invalid Folder.", "Invalid Folder", _ MessageBoxButtons.OK, MessageBoxIcon.[Error]) chkMonitor.Checked = False End If End Sub
Here, we set the various properties we’d like to interrogate.
Conclusion
As you can see, the FilesystemWatcher is quite useful and versatile. Have a play around with it and see how you can track other folder and file changes within your system.