Search code examples
vb.netwindows-servicesfilesystemwatcher

FileSystemWatcher Not Triggering Events in Windows Service Created with VB.NET


Trying to create a Windows service using VB.NET which will watch for changes in a folder using FileSystemWatcher. Service installs and starts fine but doesn't trigger any events when I add or delete a file.

The "started watcher" comment appears in the event log but I get no other event log entries.

I've researched other examples using FSW (in both VB and C#) and can't figure out what's wrong. I had the FSW details in a different class but pulled it all into one class and reduced the code as much as possible to troubleshoot. Still nothing when I create or delete a file in the watched folder.

Could it be a permissions thing? What am I missing? Thank you in advance.

Imports System.IO

Public Class TestFileWatcher

    Dim WithEvents watcher As System.IO.FileSystemWatcher
    Dim myLog As System.Diagnostics.EventLog
    Dim folderName As String
    Dim fileTypes As String

    Protected Overrides Sub OnStart(ByVal args() As String)
        ' Add code here to start your service. This method should set things
        ' in motion so your service can do its work.
        myLog = New System.Diagnostics.EventLog()
        If Not EventLog.SourceExists("My Test Log") Then
            EventLog.CreateEventSource("My Test Log", "Application")
        End If
        myLog.Source = "My Test Log"
        folderName = "C:\temp\"
        fileTypes = "*.*"
        Try
            watcher = New System.IO.FileSystemWatcher()
            DefineWatcher()
            watcher.EnableRaisingEvents = True
            myLog.WriteEntry("started watcher")
        Catch
            ErrorHandler(e)
            System.Environment.Exit(-1)     '0=successful exit
        End Try
    End Sub

    Protected Overrides Sub OnStop()
        ' Add code here to perform any tear-down necessary to stop your service.
        StopWatcher()
    End Sub

    Public Sub StopWatcher()
        watcher.Dispose()
    End Sub

    Public Sub RecordOnEventLog(ByVal str As String)
        myLog.WriteEntry(str)
    End Sub

    Protected Sub ErrorHandler(ByVal e As ApplicationException)
        Dim err As String
        err = "ERROR" + vbCrLf
        err += "Message: " + e.Message + vbCrLf
        err += "Source: " + e.Source + vbCrLf
        err += "Method: " + e.TargetSite.Name + vbCrLf
        err += "Stack Trace: " + e.StackTrace + vbCrLf
        err += "Error String: " + e.ToString + vbCrLf
        err += "Application shut down at " & My.Computer.Clock.GmtTime.ToString
        myLog.WriteEntry(err)
    End Sub

    Public Sub DefineWatcher()
        watcher.BeginInit()
        watcher.Path = folderName
        watcher.Filter = fileTypes
        watcher.IncludeSubdirectories = False
        watcher.NotifyFilter = System.IO.NotifyFilters.FileName
        watcher.NotifyFilter = watcher.NotifyFilter Or System.IO.NotifyFilters.Attributes
        watcher.NotifyFilter = watcher.NotifyFilter Or System.IO.NotifyFilters.CreationTime
        watcher.NotifyFilter = watcher.NotifyFilter Or System.IO.NotifyFilters.Security
        AddHandler watcher.Created, AddressOf OnCreated
        AddHandler watcher.Deleted, AddressOf OnDeleted
        watcher.EndInit()
    End Sub

    Public Sub OnCreated(src As Object, e As FileSystemEventArgs)
        RecordOnEventLog("New file added to temp folder, path: " + e.FullPath)
    End Sub

    Public Sub OnDeleted(src As Object, e As FileSystemEventArgs)
        RecordOnEventLog("Item deleted")
    End Sub

End Class

Solution

  • Thank you for the help. Not sure what was preventing it from working earlier but it is now working. Here is working code for anyone interested.

    Option Strict On
    
    Imports System.IO
    
    Public Class TestFileWatcher
    
        Dim watcher As System.IO.FileSystemWatcher = New System.IO.FileSystemWatcher()
        Dim myLog As System.Diagnostics.EventLog = New System.Diagnostics.EventLog()
        Dim folderName As String = "C:\temp"
        Dim fileTypes As String = "*.*"
        Dim myLogName As String = "My Test Log"
    
        Protected Overrides Sub OnStart(ByVal args() As String)
            StartLog()
            Try
                DefineWatcher()
                watcher.EnableRaisingEvents = True
                myLog.WriteEntry("started watcher hopefully")
            Catch e As Exception
                ErrorHandler(e)
                System.Environment.Exit(-1)     '0=successful exit
            End Try
        End Sub
    
        Protected Overrides Sub OnStop()
            StopWatcher()
        End Sub
    
        Private Sub StartLog()
            If Not EventLog.SourceExists(myLogName) Then
                EventLog.CreateEventSource(myLogName, "Application")
            End If
            myLog.Source = myLogName
        End Sub
    
        Private Sub StopWatcher()
            watcher.Dispose()
        End Sub
    
        Private Sub RecordOnEventLog(ByVal str As String)
            myLog.WriteEntry(str)
        End Sub
    
        Private Sub ErrorHandler(ByVal e As Exception)
            Dim err As String
            err = "ERROR" + vbCrLf
            err += "Message: " + e.Message + vbCrLf
            err += "Source: " + e.Source + vbCrLf
            err += "Method: " + e.TargetSite.Name + vbCrLf
            err += "Stack Trace: " + e.StackTrace + vbCrLf
            err += "Error String: " + e.ToString + vbCrLf
            err += "Application shut down at " & My.Computer.Clock.GmtTime.ToString
            myLog.WriteEntry(err)
        End Sub
    
        Private Sub DefineWatcher()
            watcher.BeginInit()
            watcher.Path = folderName
            watcher.Filter = fileTypes
            watcher.IncludeSubdirectories = False
            watcher.NotifyFilter = System.IO.NotifyFilters.FileName
            watcher.NotifyFilter = watcher.NotifyFilter Or System.IO.NotifyFilters.Attributes
            watcher.NotifyFilter = watcher.NotifyFilter Or System.IO.NotifyFilters.CreationTime
            watcher.NotifyFilter = watcher.NotifyFilter Or System.IO.NotifyFilters.Security
            AddHandler watcher.Created, AddressOf OnCreated
            AddHandler watcher.Deleted, AddressOf OnDeleted
            watcher.EndInit()
        End Sub
    
        Private Sub OnCreated(src As Object, e As FileSystemEventArgs)
            RecordOnEventLog("New file added to temp folder, path: " + e.FullPath)
        End Sub
    
        Private Sub OnDeleted(src As Object, e As FileSystemEventArgs)
            RecordOnEventLog("Item was deleted: " + e.FullPath)
        End Sub
    
    End Class