Solved

VB.net Filesystem watcher not working

Posted on 2017-04-12
5
31 Views
Last Modified: 2017-04-17
Good Afternoon,

I can't seem to get my FileSystemWatcher to work. I want it to display the results of the watch folder in a list box. But when I copy a file to the watched directory no data is written to the list box control. Please note that I am not getting any errors.

Kindly advise if I am missing something.

Code is below.

Public Class frmConfigurations

    'Connection Variables
    Dim conn As SqlConnection
    Dim connectionString = SQLConnString()
    Dim sql As String

    'WatchFolder Variables
    Public watchfolder As FileSystemWatcher
    Public str As String = ""

Open in new window


Private Sub frmConfigurations_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

        Try

            conn = New SqlConnection(connectionString)
            conn.Open()

            sql = "SELECT ID, ClientNumber, OfficerName, OfficerEmail, AssistantName, AssistantEmail FROM Contacts ORDER BY ClientNumber"

            Dim dscmd As New SqlDataAdapter(sql, conn)
            dscmd.SelectCommand.CommandTimeout = 60

            Dim ds As New DataSet
            dscmd.Fill(ds)

            dgvData.DataSource = ds.Tables(0)

        Catch ex As Exception
            MsgBox(ErrorToString)

        Finally
            conn.Close()

        End Try

        'Set the Monitoring Directory
        txtWatchPath.Text = My.Computer.FileSystem.SpecialDirectories.MyDocuments & "\GlobusMailWatch"

        'Create the monitoring directory if it does not exist already
        If Not Directory.Exists(txtWatchPath.Text) Then
            Directory.CreateDirectory(txtWatchPath.Text)
        End If   

Open in new window


Private Sub btnStart_Click(sender As System.Object, e As System.EventArgs) Handles btnStart.Click

        btnStart.Enabled = False
        btnStop.Enabled = True
        txtMonStatus.Text = "Started"

        'Prepare to handle the monitoring folder
        subInitializeWatchFolder()

    End Sub

Open in new window


Private Sub subInitializeWatchFolder()

        watchfolder = New FileSystemWatcher

        'This is the path we are monitoing
        watchfolder.Path = txtWatchPath.Text

        'Watch for changes
        watchfolder.NotifyFilter = NotifyFilters.CreationTime

        'Only watch for .MSG files
        watchfolder.Filter = "*.msg"

        'Event Handlers
        AddHandler watchfolder.Created, AddressOf logCreated
        AddHandler watchfolder.Deleted, AddressOf logDeleted

        'Start monitoring folder
        watchfolder.EnableRaisingEvents = True

    End Sub

Open in new window


Private Sub logCreated(ByVal source As Object, ByVal e As System.IO.FileSystemEventArgs)

        str = e.FullPath

        lsbxLog.Items.Add("CREATED: " & str)

    End Sub

    Private Sub logDeleted(ByVal source As Object, ByVal e As System.IO.FileSystemEventArgs)

        str = e.FullPath

        lsbxLog.Items.Add("DELETED: " & str)

    End Sub

Open in new window

0
Comment
Question by:nobushi
  • 2
  • 2
5 Comments
 
LVL 70

Expert Comment

by:Éric Moreau
ID: 42090865
have you tried to handle the .Changed event? Have a look at http://emoreau.com/Entries/Articles/2005/04/The-FileSystemWatcher-component.aspx
0
 
LVL 33

Expert Comment

by:it_saige
ID: 42091864
I think you might be trying to do something like this:
Form1.vb -
Imports System.ComponentModel
Imports System.IO
Imports System.Threading

Public Class Form1
    Private isRunning = False
    Private lastChangedTime As DateTime = DateTime.Now
    Private lastFilePath As String = String.Empty
    Private ReadOnly QueuedFiles As New List(Of ProcessableFile)
    WithEvents watchfolder As FileSystemWatcher
    WithEvents worker As New BackgroundWorker With {.WorkerReportsProgress = True, .WorkerSupportsCancellation = True}

    Private Sub OnLoad(sender As Object, e As EventArgs) Handles MyBase.Load
        'Create the monitoring directory if it does not exist already
        If Not Directory.Exists(Path.Combine(My.Computer.FileSystem.SpecialDirectories.MyDocuments, "GlobusMailWatch")) Then
            Directory.CreateDirectory(Path.Combine(My.Computer.FileSystem.SpecialDirectories.MyDocuments, "GlobusMailWatch"))
        End If
        isRunning = True
        worker.RunWorkerAsync()
        InitializeWatchFolder(Path.Combine(My.Computer.FileSystem.SpecialDirectories.MyDocuments, "GlobusMailWatch"))
    End Sub

    Private Sub InitializeWatchFolder(path As String)
        watchfolder = New FileSystemWatcher(path, "*.msg") With {.EnableRaisingEvents = True}
    End Sub

    Private Sub LogAction(ByVal source As Object, ByVal e As System.IO.FileSystemEventArgs) Handles watchfolder.Created, watchfolder.Deleted, watchfolder.Changed
        Try
            Dim span = DateTime.Now.Subtract(lastChangedTime)
            If isRunning AndAlso span.TotalSeconds > 2 OrElse lastFilePath <> e.FullPath Then
                ' Wait a second for any locks to be released before taking actions
                Thread.Sleep(1000)
                Select Case e.ChangeType
                    Case WatcherChangeTypes.Created
                        lastChangedTime = DateTime.Now
                        lastFilePath = e.FullPath
                        Dim match = (From pFile In QueuedFiles Where pFile.File.FullName.Equals(e.FullPath, StringComparison.OrdinalIgnoreCase) Select pFile).SingleOrDefault()
                        If match Is Nothing Then
                            SyncLock (QueuedFiles)
                                QueuedFiles.Add(New ProcessableFile(New FileInfo(e.FullPath)))
                            End SyncLock
                        End If
                        Exit Select
                    Case WatcherChangeTypes.Deleted
                        lastChangedTime = DateTime.Now
                        lastFilePath = e.FullPath
                        Dim match = (From pFile In QueuedFiles Where pFile.File.FullName.Equals(e.FullPath, StringComparison.OrdinalIgnoreCase) Select pFile).SingleOrDefault()
                        If match IsNot Nothing Then
                            SyncLock (QueuedFiles)
                                QueuedFiles.Remove(match)
                            End SyncLock
                        End If
                        Exit Select
                End Select
                worker.ReportProgress(0, String.Format("{0}: {1}", e.ChangeType.ToString().ToUpper(), e.FullPath))
            End If
        Catch ex As Exception
            Console.WriteLine("Exception reported - {0}", ex)
        End Try
    End Sub

    Private Sub OnDoWork(sender As Object, e As DoWorkEventArgs) Handles worker.DoWork
        Try
            While (isRunning)
                SyncLock (QueuedFiles)
                    For i As Integer = QueuedFiles.Count - 1 To 0 Step -1
                        If Not QueuedFiles(i).IsProcessing Then
                            'Simulating a long process
                            Thread.Sleep(10000)
                            Console.WriteLine("Processing new item - {0}", QueuedFiles(i).File.FullName)
                            QueuedFiles(i).IsProcessing = True
                        Else
                            If Not QueuedFiles(i).IsProcessed Then
                                Console.WriteLine("Finished processing - {0}", QueuedFiles(i).File.FullName)
                                QueuedFiles(i).IsProcessed = True
                            Else
                                QueuedFiles(i).File.Delete()
                            End If
                        End If
                    Next
                End SyncLock
            End While
        Catch ex As Exception

        End Try
    End Sub

    Private Sub OnProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles worker.ProgressChanged
        ListBox1.Items.Add(CType(e.UserState, String))
    End Sub

    Private Sub OnClosing(sender As Object, e As CancelEventArgs) Handles Me.Closing
        isRunning = False
        worker.CancelAsync()
    End Sub
End Class

Class ProcessableFile
    Private ReadOnly fFile As FileInfo
    Public ReadOnly Property File() As FileInfo
        Get
            Return fFile
        End Get
    End Property

    Public Property IsProcessing() As Boolean
    Public Property IsProcessed() As Boolean

    Public Sub New(ByVal [file] As FileInfo)
        fFile = file
    End Sub
End Class

Open in new window

Form1.Designer.vb -
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
    Inherits System.Windows.Forms.Form

    'Form overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Me.ListBox1 = New System.Windows.Forms.ListBox()
        Me.SuspendLayout()
        '
        'ListBox1
        '
        Me.ListBox1.Dock = System.Windows.Forms.DockStyle.Fill
        Me.ListBox1.FormattingEnabled = True
        Me.ListBox1.Location = New System.Drawing.Point(0, 0)
        Me.ListBox1.Name = "ListBox1"
        Me.ListBox1.Size = New System.Drawing.Size(707, 261)
        Me.ListBox1.TabIndex = 0
        '
        'Form1
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(707, 261)
        Me.Controls.Add(Me.ListBox1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(False)

    End Sub

    Friend WithEvents ListBox1 As ListBox
End Class

Open in new window

Which produces the following output -Capture.PNG
-saige-
0
 
LVL 1

Author Comment

by:nobushi
ID: 42092436
Good Afternoon,

@Eric, Yes I have tried to hand the .Changed event, but its the same result when I attempt. Nothing appears in the listbox control and I receive no errors.

@it_saige, thank you for taking the time to write all that code. While it does work I feel a little overwhelmed as I don't understand a lot of it. I'm still quite the beginner. So I don't feel comfortable incorporating it in to my project as if something needs changing I won't know where to proceed with my current skill set.

Are you able to look at my current code and advise if something is missing or not correct?

Kindly advise.

Regards,
N
0
 
LVL 33

Accepted Solution

by:
it_saige earned 500 total points
ID: 42092973
Start by removing your notify filter; e.g. -
Imports System.IO

Module Module1
    Private WithEvents watcher As FileSystemWatcher

    Sub Main()
        If Not Directory.Exists(Path.Combine(My.Computer.FileSystem.SpecialDirectories.MyDocuments, "GlobusMailWatch")) Then
            Directory.CreateDirectory(Path.Combine(My.Computer.FileSystem.SpecialDirectories.MyDocuments, "GlobusMailWatch"))
        End If
        InitializeWatchFolder(Path.Combine(My.Computer.FileSystem.SpecialDirectories.MyDocuments, "GlobusMailWatch"))
        Console.WriteLine("Watcher started...  Press any key to exit...")
        Console.ReadKey()
    End Sub

    Sub InitializeWatchFolder(path As String)
        watcher = New FileSystemWatcher(path, "*.msg") With {.EnableRaisingEvents = True}
    End Sub

    Sub LogAction(source As Object, e As FileSystemEventArgs) Handles watcher.Created, watcher.Deleted
        Console.WriteLine("{0}: {1}", e.ChangeType.ToString().ToUpper(), e.FullPath)
    End Sub
End Module

Open in new window

Produces the following output -Capture.PNG
-saige-
0
 
LVL 1

Author Closing Comment

by:nobushi
Thank you very much for your assistance it_saige.
0

Featured Post

Space-Age Communications Transitions to DevOps

ViaSat, a global provider of satellite and wireless communications, securely connects businesses, governments, and organizations to the Internet. Learn how ViaSat’s Network Solutions Engineer, drove the transition from a traditional network support to a DevOps-centric model.

Join & Write a Comment

Suggested Solutions

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

685 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question