This article demonstrates through code how to recursively search subdirectories for files, starting with a root directory. A search string is specified so that you can search for files that match a certain criteria. Each part of the code is explained as necessary. A working code sample is also provided at the end of the article.
Directory recursion is a common IO task for developers. The
FileSystemObject makes this task easy for Component Object Model (COM) applications. Now this task has become even easier in the Microsoft .NET Framework. Similar to the
FileSystemObject, the classes in the
System.IO namespace provide an object-oriented way to access files and directories.
Requirements
The following list outlines the recommended hardware, software, network infrastructure, and service packs that you need:- Microsoft Visual Studio 2005 or Microsoft Visual Studio .NET
Microsoft provides programming examples for illustration only, without warranty either expressed or implied. This includes, but is not limited to, the implied warranties of merchantability or fitness for a particular purpose. This article assumes that you are familiar with the programming language that is being demonstrated and with the tools that are used to create and to debug procedures. Microsoft support engineers can help explain the functionality of a particular procedure, but they will not modify these examples to provide added functionality or construct procedures to meet your specific requirements.
Directory recursion
The file and directory manipulation classes reside in the
System.IO namespace. Before you work with these classes, you should import the following namespace into your project.
The
System.IO namespace classes provide many options for working with files and directories. The
System.IO namespace not only provides classes that you can instantiate, it also provides file and directory utility classes. These classes contain shared methods that you can call without having to declare a variable of that type. For example, you can use the
Directory object to obtain the subdirectories of a given directory.
The following code uses the shared
GetDirectories method of the
Directory object to return an array of strings. This array contains directory path names to the subdirectories of the C:\ directory, if any.
Dim directories() As String = Directory.GetDirectories("C:\")
The
Directory object also contains the
GetFiles method. The
GetFiles method lets you retrieve a string array of files that match a certain criteria. The following code sample uses the
File object to retrieve all of the files in the C:\ directory that end with a .dll extension.
Dim files() As String = Directory.GetFiles("C:\", "*.dll")
The
GetDirectories method and the
GetFiles method of the
Directory object are all that you need to recursively search for files that match the search string. The following method is used to perform the recursion.
Sub DirSearch(ByVal sDir As String)
Dim d As String
Dim f As String
Try
For Each d In Directory.GetDirectories(sDir)
For Each f In Directory.GetFiles(d, txtFile.Text)
lstFilesFound.Items.Add(f)
Next
DirSearch(d)
Next
Catch excpt As System.Exception
Debug.WriteLine(excpt.Message)
End Try
End Sub
The preceding code passes a string, which contains the directory that you want to search, to
DirSearch. This string value is the full path name of the directory. You can use the
GetDirectories method to retrieve the subdirectories of the directory that is passed into your procedure. Because the
GetDirectories method returns an array, you can use a for/each statement to iterate over each subdirectory. For each subdirectory, use the
GetFiles method to iterate over the files in that directory. The value of the text box on your form is passed to the
GetFiles method. The text box contains the search string that filters the results that the
GetFiles method returns. If any files match the search criteria, they are added to your list box. For each subdirectory that is located, call
DirSearch again, and pass it a subdirectory. By using this recursive call, you can search all subdirectories of a given root directory.
Complete code sample
- Start a new Microsoft Visual Basic 2005 or Microsoft Visual Basic .NET Windows Application project. By default, a form that is named Form1 is created.
- On the View menu, click to display Solution Explorer.
- In Solution Explorer, right-click Form1, and then click View Code.
- In the Form1 code window, highlight and then delete all the existing code.
- Paste the following code in the code window of the Form1 form.
Imports System.IO
Public Class Form1
Inherits System.Windows.Forms.Form
#Region " Windows Form Designer generated code "
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call.
End Sub
'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
Friend WithEvents cboDirectory As System.Windows.Forms.ComboBox
Friend WithEvents txtFile As System.Windows.Forms.TextBox
Friend WithEvents lstFilesFound As System.Windows.Forms.ListBox
Friend WithEvents lblDirectory As System.Windows.Forms.Label
Friend WithEvents lblFile As System.Windows.Forms.Label
Friend WithEvents btnSearch As System.Windows.Forms.Button
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer.
'You can use the Windows Form Designer to modify it; however, do not
'use the code editor to modify it.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.btnSearch = New System.Windows.Forms.Button()
Me.lblFile = New System.Windows.Forms.Label()
Me.cboDirectory = New System.Windows.Forms.ComboBox()
Me.txtFile = New System.Windows.Forms.TextBox()
Me.lstFilesFound = New System.Windows.Forms.ListBox()
Me.lblDirectory = New System.Windows.Forms.Label()
Me.SuspendLayout()
'
'btnSearch
'
Me.btnSearch.Location = New System.Drawing.Point(608, 248)
Me.btnSearch.Name = "btnSearch"
Me.btnSearch.TabIndex = 0
Me.btnSearch.Text = "Search"
'
'lblFile
'
Me.lblFile.Location = New System.Drawing.Point(8, 16)
Me.lblFile.Name = "lblFile"
Me.lblFile.Size = New System.Drawing.Size(144, 16)
Me.lblFile.TabIndex = 5
Me.lblFile.Text = "Search for files containing:"
'
'cboDirectory
'
Me.cboDirectory.DropDownWidth = 112
Me.cboDirectory.Location = New System.Drawing.Point(8, 128)
Me.cboDirectory.Name = "cboDirectory"
Me.cboDirectory.Size = New System.Drawing.Size(120, 21)
Me.cboDirectory.TabIndex = 2
Me.cboDirectory.Text = "ComboBox1"
'
'txtFile
'
Me.txtFile.Location = New System.Drawing.Point(8, 40)
Me.txtFile.Name = "txtFile"
Me.txtFile.Size = New System.Drawing.Size(120, 20)
Me.txtFile.TabIndex = 4
Me.txtFile.Text = "*.dll"
'
'lstFilesFound
'
Me.lstFilesFound.Location = New System.Drawing.Point(152, 8)
Me.lstFilesFound.Name = "lstFilesFound"
Me.lstFilesFound.Size = New System.Drawing.Size(528, 225)
Me.lstFilesFound.TabIndex = 1
'
'lblDirectory
'
Me.lblDirectory.Location = New System.Drawing.Point(8, 96)
Me.lblDirectory.Name = "lblDirectory"
Me.lblDirectory.Size = New System.Drawing.Size(120, 23)
Me.lblDirectory.TabIndex = 3
Me.lblDirectory.Text = "Look In:"
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(688, 273)
Me.Controls.AddRange(New System.Windows.Forms.Control() _
{Me.lblFile, Me.txtFile, Me.lblDirectory, Me.cboDirectory, _
Me.lstFilesFound, Me.btnSearch})
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)
End Sub
#End Region
Private Sub btnSearch_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnSearch.Click
lstFilesFound.Items.Clear()
txtFile.Enabled = False
cboDirectory.Enabled = False
btnSearch.Text = "Searching..."
Me.Cursor = Cursors.WaitCursor
Application.DoEvents()
DirSearch(cboDirectory.Text)
btnSearch.Text = "Search"
Me.Cursor = Cursors.Default
txtFile.Enabled = True
cboDirectory.Enabled = True
End Sub
Sub DirSearch(ByVal sDir As String)
Dim d As String
Dim f As String
Try
For Each d In Directory.GetDirectories(sDir)
For Each f In Directory.GetFiles(d, txtFile.Text)
lstFilesFound.Items.Add(f)
Next
DirSearch(d)
Next
Catch excpt As System.Exception
Debug.WriteLine(excpt.Message)
End Try
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim s As String
cboDirectory.Items.Clear()
For Each s In Directory.GetLogicalDrives()
cboDirectory.Items.Add(s)
Next
cboDirectory.Text = "C:\"
End Sub
End Class
Note You must change the code in Visual Basic 2005. By default, Visual Basic creates two files for the project when you create a Windows Forms project. If the form is named Form1, the two files that represent the form are named Form1.vb and Form1.Designer.vb. You write the code in the Form1.vb file. The Windows Forms Designer writes the code in the Form1.Designer.vb file. The Windows Forms Designer uses the partial keyword to divide the implementation of Form1 into two separate files. This behavior prevents the designer-generated code from being interspersed with your code.
For more information about the new Visual Basic 2005 language enhancements, visit the following Microsoft Developer Network (MSDN) Web site: For more information about partial classes and the Windows Forms Designer, visit the following MSDN Web site: - Press F5 to build and run the sample.