FileSystemWatcher Class in VB.NET

 

FileSystemWatcher in VB Example
FileSystemWatcher in VB Example

Just a quick post on using the Microsoft file system watcher component in the .Net framework with Visual Basic. Utilizing the Microsoft file system watcher component in .Net with Visual Basic, you’re able to watch a directory structure for changes to its contents and respond with Visual Basic code.

Using the.net file watching component is pretty simple on the surface. Microsoft provides enough example code in their documentation to give any new user a great head start. Basically, to use the file system watcher component you have to first set permissions to full trust, create a new file system watcher object, set its properties, create handlers for the events the file system watcher object raises, and then set it to enable raising events.

When I first started tinkering around with the file system watcher component everything worked as expected. I did, after watching the events closely, come across one caveat. If you set the file system watcher object to include subdirectories, when you delete a subdirectory that has files contained in it the event raised by the file system watcher will only show the event for that subdirectory being deleted not for any of the files contained in that directory. This makes it a bit more difficult to keep track of the directory structure.

My solution was to create a list in order to compare file paths of the files contained in the folder to the path of the sub folder being deleted. Eventually, I found it easier to break this functionality off into a new class that I could adapt for reuse. I felt that using a list to keep track of the folders and files was better for performance then re-parsing the file system every time a subfolder was deleted. I wrote a simple dialog project for demonstration purposes that I’ll post on github so that you can check out the code.

 

Reference:

https://docs.microsoft.com/en-us/dotnet/api/system.io?view=netframework-4.7

https://docs.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher?view=netframework-4.7

 

 

Example Code on Github

Imports System.IO
Imports System.Security
Imports System.Security.Permissions

''' <summary>
''' Singleton that initializes and handles file watcher changes
''' </summary>

<CLSCompliant(True)> Public Class MyDirectory
    Public Shared Event Change(path As String)
    Public Shared Event Create(path As String)
    Public Shared Event Delete(path As String)
    Public Shared Event Renamed(oldpath As String, newpath As String)
    Private Shared watched As String
    Private Shared retList As List(Of String)
    Public Shared ReadOnly Property Count As Integer
        Get
            Return retList.Count
        End Get
    End Property
    Private Sub New()
    End Sub
    Public Shared Function ListDirectory(path As String) As List(Of String)
        retList = New List(Of String)
        watched = path
        Try
            Dim di As DirectoryInfo = New DirectoryInfo(path)
            For Each file In di.EnumerateFiles("*", SearchOption.AllDirectories)
                retList.Add(file.FullName)
            Next
            For Each folder In di.EnumerateDirectories("*", SearchOption.AllDirectories)
                retList.Add(folder.FullName)
            Next
        Catch ex As DirectoryNotFoundException
            Console.WriteLine("Directory not found: {0}", ex.Message)
        Catch ex As SecurityException
            Console.WriteLine("Security Exception:\n\n{0}", ex.Message)
        Catch ex As Exception
            Console.WriteLine("Exception occurred: {0}", ex.Message)
        End Try
        Return retList
    End Function
    <PermissionSet(SecurityAction.Demand, Name:="FullTrust")>
    Public Shared Sub WatchDirectory(path As String)
        Dim fswatcher As New FileSystemWatcher
        fswatcher.IncludeSubdirectories = True
        fswatcher.Path = path
        fswatcher.Filter = ""
        AddHandler fswatcher.Changed, AddressOf onChanged
        AddHandler fswatcher.Created, AddressOf onCreated
        AddHandler fswatcher.Deleted, AddressOf onDeleted
        AddHandler fswatcher.Renamed, AddressOf onRenamed
        fswatcher.EnableRaisingEvents = True
    End Sub
    Private Shared Sub onChanged(src As Object, evt As FileSystemEventArgs)
        RaiseEvent Change(evt.FullPath)
    End Sub
    Private Shared Sub onDeleted(src As Object, evt As FileSystemEventArgs)
        Dim tList As List(Of String) = New List(Of String)
        Dim thepath As String = evt.FullPath
        For Each path As String In retList
            If path.StartsWith(thepath) Then
                tList.Add(path)
            End If
        Next
        For Each path As String In tList
            retList.Remove(path)
            RaiseEvent Delete(path)
        Next
    End Sub
    Private Shared Sub onCreated(src As Object, evt As FileSystemEventArgs)
        retList.Add(evt.FullPath)
        RaiseEvent Create(evt.FullPath)
    End Sub
    Private Shared Sub onRenamed(src As Object, evt As RenamedEventArgs)
        Dim thepath As String = evt.OldFullPath
        Dim fname As String = ""
        Dim dicRename As Dictionary(Of String, String) = New Dictionary(Of String, String)
        For Each path As String In retList
            If path.StartsWith(thepath) Then
                If Equals(path, thepath) Then
                    dicRename.Add(path, evt.FullPath)
                Else
                    fname = path.Substring(path.LastIndexOf("\") + 1)
                    dicRename.Add(path, evt.FullPath & "\" & fname)
                End If
            End If
        Next
        For Each KVPair As KeyValuePair(Of String, String) In dicRename
            retList.Remove(KVPair.Key)
            retList.Add(KVPair.Value)
            'Console.WriteLine("Renamed from: {0} \n To: {1}", KVPair.Key, KVPair.Value)
            RaiseEvent Renamed(KVPair.Key, KVPair.Value)
        Next
    End Sub
End Class

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s