Kevin
asked on
VB.net Filesystem watcher not working
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.
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 = ""
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
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
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
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
have you tried to handle the .Changed event? Have a look at http://emoreau.com/Entries/Articles/2005/04/The-FileSystemWatcher-component.aspx
I think you might be trying to do something like this:
Form1.vb -
-saige-
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
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
Which produces the following output --saige-
ASKER
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
@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
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you very much for your assistance it_saige.