Imports System.IO
Public Class SearchFilesFrm3
' To set up for a background operation, add an event handler for the DoWork event.
' Call your time-consuming operation in this event handler. To start the operation,
' call RunWorkerAsync. To receive notifications of progress updates, handle the
' ProgressChanged event. To receive a notification when the operation is completed,
' handle the RunWorkerCompleted event.
' Note
' You must be careful not to manipulate any user-interface objects in your DoWork
' event handler. Instead, communicate to the user interface through the
' ProgressChanged and RunWorkerCompleted events.
' If your background operation requires a parameter, call RunWorkerAsync with your
' parameter. Inside the DoWork event handler, you can extract the parameter from
' the DoWorkEventArgs.Argument property.
' Store the directory to search
Private strDir As String
' Store the results of the search
Private Files As List(Of String)
' Used to prevent nested calls to ProgressChanged
Private CallInProgress As Boolean
' The Worker thread
Private WithEvents BgWorker As New System.ComponentModel.BackgroundWorker
Private Sub SearchFilesFrm3_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles Me.Load
If strDir = "" Then
txtSearchPath.Text = "F:\ELIXIR"
txtSearchPattern.Text = "*.*"
End If
' Enable ProgressChanged and Cancellation mothed
BgWorker.WorkerReportsProgress = True
BgWorker.WorkerSupportsCancellation = True
End Sub
' Start and Stop the search
Private Sub btnStart_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles btnStart.Click
If btnStart.Text = "Start" Then
If Not Directory.Exists(txtSearchPath.Text.Trim()) Then
MessageBox.Show("The Search Directory does not exist", _
"Path Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Return
End If
If txtSearchPattern.Text.Trim() = "" Then
txtSearchPattern.Text = "*.*"
End If
Dim arguments() As String = {txtSearchPath.Text.Trim(), _
txtSearchPattern.Text.Trim()}
lstFiles.Items.Clear()
' Start the background worker thread. Thread runs in DoWork event.
BgWorker.RunWorkerAsync(arguments)
btnStart.Text = "Stop"
Me.Refresh()
Else
BgWorker.CancelAsync()
End If
End Sub
' Start the Asynchronous file search. The background thread does it work from
' this event.
Private Sub BgWorker_DoWork(ByVal sender As Object, _
ByVal e As System.ComponentModel.DoWorkEventArgs) _
Handles BgWorker.DoWork
'Retrieve the search path which was requested
Dim path As String = DirectCast(e.Argument, String())(0)
Dim pattern As String = DirectCast(e.Argument, String())(1)
' Invoke the worker procedure
Files = New List(Of String)
SearchFiles(path, pattern)
' Return a result to the RunWorkerCompleted event
Dim message As String = String.Format("Found {0} Files", Files.Count)
e.Result = message
End Sub
' Recursively search directory and sub directories
Private Sub SearchFiles(ByVal path As String, _
ByVal pattern As String)
' Displat message
Dim message As String = String.Format("Parsing Directory {0}", path)
BgWorker.ReportProgress(0, message)
'Read the files and if the Stop button is pressed cancel the operation
Try
For Each fileName As String In Directory.GetFiles(path, pattern)
If BgWorker.CancellationPending Then Return
Files.Add(fileName)
Next
Catch ex As Exception
MsgBox("You will see this")
End Try
'This will cause it to list files in sub directorys
'Try
' For Each dirName As String In Directory.GetDirectories(path)
' If BgWorker.CancellationPending Then Return
' SearchFiles(dirName, pattern)
' Next
'Catch ex As Exception
' MsgBox("You might see this")
'End Try
End Sub
' The bacground thread calls this event when you make a call to ReportProgress
' It is OK to access user controls in the UI from this event.
' If you use a Progress Bar or some other control to report the tasks progress
' you should avoid unnecessary calls to ReportProgress method because this causes
' a thread switch which is a relatively expensive in terms of processing time.
Private Sub BgWorker_ProgressChanged(ByVal sender As Object, _
ByVal e As System.ComponentModel.ProgressChangedEventArgs) _
Handles BgWorker.ProgressChanged
' Reject a nested call.
If CallInProgress Then Return
CallInProgress = True
' Display the message received in the UserState property
lblMessage.Text = e.UserState.ToString()
' Display all files added since last call.
For idx As Integer = lstFiles.Items.Count To Files.Count - 1
lstFiles.Items.Add(Files(idx))
Next
' If a Me.Refresh is in this code you will need to place a Application.DoEvents()
' otherwise the UI will not respond without them it works fine.
' Me.Refresh()
' Let the Windows OS process messages in the queue
' Application.DoEvents()
CallInProgress = False
End Sub
' The background thread calls this event just before it reaches the End Sub
' of the DoWork event. It is OK to access user controls in the UI from this event.
Private Sub BgWorker_RunWorkerCompleted(ByVal sender As Object, _
ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) _
Handles BgWorker.RunWorkerCompleted
' Display the last message and reset the Start/Stop button text
lblMessage.Text = e.Result.ToString()
btnStart.Text = "Start"
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button1.Click
' First create a FolderBrowserDialog object
Dim FolderBrowserDialog1 As New FolderBrowserDialog
' Then use the following code to create the Dialog window
' Change the .SelectedPath property to the default location
With FolderBrowserDialog1
' Desktop is the root folder in the dialog.
.RootFolder = Environment.SpecialFolder.Desktop
' Select the C:\Windows directory on entry.
'>>>>.SelectedPath = "c:\windows"
.SelectedPath = txtSearchPath.Text
' Prompt the user with a custom message.
.Description = "Select the source directory"
If .ShowDialog = DialogResult.OK Then
' Display the selected folder if the user clicked on the OK button.
'MessageBox.Show(.SelectedPath)
txtSearchPath.Text = .SelectedPath
End If
End With
End Sub
End Class