Monitoring a Folder and E-mailing New Files as Attachments Using a VB.NET FolderWatcher
Back when I was a VB developer, we had a partner who regularly copied files to a mapped network drive folder. Our system was supposed to immediately process the file, because the data that it contained was time sensitive. We had to rely on Windows APIs—and a lot of code—to monitor the folder. Thankfully, those days are over! Now, we can monitor a folder and raise events when there is any activity in the target folder by using the FileSystemWatcher class. It gets even better. VB.NET has a encapsulated all of the functionality of the System.IO.FileSystemWatcher class into a control that you can add to your VB.NET projects. In this article, we’ll create a simple application in Visual Studio that will respond to the File Create event and e-mail the new file to us as an attachment via our Gmail account.
Creating the Project
Because the control is built on top of Microsoft Visual Basic .NET, if you want to follow along with this article, you will need the .NET Framework as well as Visual Studio. You’ll be happy to know that Microsoft offers the FREE Visual Studio Community Edition, a fully-featured, extensible, IDE for creating Android, iOS, Windows, and Web applications, as well as Cloud services.
When you run the installer, make sure that you check the “Universal Windows Platform Development” and “.NET desktop development” boxes. The first contains the VB language; the latter, the .NET classes, including the “Windows.Form” component. It’s a large download, but fortunately, you only need to do it once.
Figure 1: Visual Studio Community 2017 installer
If you make the same mistake as I did and only install the basic IDE components, you can always get back to the installer at any time because it is installed along with the IDE. Microsoft has some clear and concise instructions on how to do just that.
Launch Visual Studio and create a new Visual Basic Windows Form App:
Figure 2: New Project dialog
Give your project a name and click the OK button to close the New Project dialog and create the project.
Designing the Main Form
Our form requires three visible controls: a button for selecting the folder to watch, a label that shows the watched folder, and a drop-down listbox that outputs event information:
Figure 3: FileSystemWatcher form
Now, we’ll add the FolderBrowserDialog control.
Unlike your typical Windows Forms control, a FolderBrowserDialog does not have any visual properties and is not visible on the form.
To add an invisible control at design time, you simply drag and drop the control from the Toolbox to your Form in Visual Studio. The FolderBrowserDialog is located under “Dialogs” in the Toolbox:
Figure 4: FolderBrowserDialog component
The FileSystemWatcher class is one that can raise events when a file is created, renamed, updated, or deleted within the specified folder. The FileSystemWatcher control is simply a component version of that class that can be edited within the designer.
Figure 5: FileSystemWatcher component
After you’ve added the FolderBrowserDialog and FileSystemWatcher components to the form, the designer looks like this:
Figure 6: Form designer with added components
Coding the Main Form
In the code pane, we’ll need to write two Sub routines: one for the Browse button Click event and another for the FileSystemWatcher Created event.
The code editor should already have some basic code, including import statements and the form class.
Inside the form class (named “frmFileWatcher” below), enter the following code:
Public Class frmFileWatcher Private Sub btnBrowseForWatchFolder_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) Handles _ btnBrowseForWatchFolder.Click fbd1.ShowDialog() lblWatchFolder.Text = fbd1.SelectedPath fsw1.Path = lblWatchFolder.Text MsgBox("Path to monitor is now set to: " & _ lblWatchFolder.Text) End Sub End Class
Now, clicking the Browse button (named “btnBrowseForWatchFolder”) will show the FolderBrowserDialog (named “fbd1”), set the accompanying label (“lblWatchFolder”)’s text, and FileSystemWatcher (“fsw1”)’s path to the selected path.
Here is the code for the fsw1_Created handler:
Private Sub fsw1_Created(ByVal sender As Object, ByVal e As _ System.IO.FileSystemEventArgs) Handles fsw1.Created lstWatchResults.Items.Add("File " & e.FullPath.ToString & _ " created at: " & System.DateTime.Now) Dim oAttch As Attachment = New Attachment(e.FullPath.ToString) Try Dim Smtp_Server As New SmtpClient Dim e_mail As New MailMessage() Smtp_Server.UseDefaultCredentials = False Smtp_Server.Credentials = New Net.NetworkCredential _ ("firstname.lastname@example.org", "<your password>") Smtp_Server.Port = 587 Smtp_Server.EnableSsl = True Smtp_Server.Host = "smtp.gmail.com" e_mail.From = New MailAddress("email@example.com") e_mail.To.Add("firstname.lastname@example.org") e_mail.Subject = "Sales spreadsheet" e_mail.IsBodyHtml = False e_mail.Body = "Sending " & e.Name & "." e_mail.Attachments.Add(oAttch) Smtp_Server.Send(e_mail) lstWatchResults.Items.Add("Mail Sent") Catch error_t As Exception lstWatchResults.Items.Add(error_t.ToString) End Try End Sub
Having set the FileSystemWatcher’s path to the selected folder, the preceding code will run whenever a file is either created or added to the target folder.
The bulk of the code configures a new e-mail message and attaches the file to it. This method of e-mail delivery employs the Gmail SMTP server. Just be sure to turn on “allow less secure apps” from your Google console:
Figure 7: Google’s allow less secure apps feature
The Finished Product
Click the Run button to try out your app. Then, either create a new file or copy and paste one into the target folder, to fire the Created event. This is what my app displayed when I did that:
Figure 8: FileSystemWatcher app in action
Here is the full source code for this tutorial. You can simply paste it in your code editor, but make sure to set the constants to your own Gmail credentials and e-mail addresses!
Although the way that we dynamically configured the FileSystemWatcher’s path in this tutorial might make you wonder why we didn’t just instantiate the underlying class directly, there are some distinct advantages to using a control. We’ll explore some of these in upcoming articles, using this project as the starting point.