Solved

VB.net Filesystem watcher not working

Posted on 2017-04-12
5
74 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 34

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 34

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
ID: 42095888
Thank you very much for your assistance it_saige.
0

Featured Post

Get free NFR key for Veeam Availability Suite 9.5

Veeam is happy to provide a free NFR license (1 year, 2 sockets) to all certified IT Pros. The license allows for the non-production use of Veeam Availability Suite v9.5 in your home lab, without any feature limitations. It works for both VMware and Hyper-V environments

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…

623 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