# VBForums CodeBank > CodeBank - Visual Basic .NET >  VB.NET - Search directories, subdirectories for files, excluding files by name or ext

## Peter Porter

Written in VB.NET 2010, the below code searches a select directory and it's subdirectories for all files... gets file extensions and excludes files by select extensions from whatever function you want to perform, like deletion, copying, whatever, all while it's recording how many times it loops, not counting excluded files from skipped loops. To test the code, you'll gonna need one button, a label called "Processed:" next to a textbox.

Note: The .suo file extension, which is a file extension I excluded in the code below, is a hidden file VB.NET adds to your projects with the same project name. The program only works by ignoring hidden .suo and .ini files.

Hope someone finds this helpful!



```
Option Strict On

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim i as integer = 0

         'Target Directory
        Dim directory = "C:\Users\Peter\Desktop\TestFolder\"

          'Searches directory and it's subdirectories for all files, which "*" stands for
          'Say for example you only want to search for jpeg files... then change "*" to "*.jpg"  
        For Each filename As String In IO.Directory.GetFiles(directory, "*", IO.SearchOption.AllDirectories)

             'The next line of code gets only file extensions from searched directories and subdirectories
            Dim fName As String = IO.Path.GetExtension(filename)

            If fName = ".suo" Then
                
                'Skips to next iteration of Loop, ignoring files with .suo extension 
                Continue For

            Else
                If fName = ".ini" Then

                    'Skips to next iteration of Loop, ignoring files with .ini extension
                    Continue For

                Else

                    'Your code here above count function
                    'The below counter only displays the final count after all files have been processed

                    i = i + 1
                    TextBox1.Text = Convert.ToString(i)

                End If
            End If
        Next
    End Sub
End Class
```

If you would like to filter files by name, copy the fName array line, change fName to fName2 and change GetExtension to GetFileName or GetFileNameWithoutExtension from your new array. You then would have to create If Then statements for this new array. Like I stated above, this program only works by ignoring .suo and .ini files, so I wouldn't change anything, but add to above.

----------


## Peter Porter

```
Option Strict On

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim i as integer = 0

         'Target Directory
        Dim directory = "C:\Users\Peter\Desktop\TestFolder\"

          'Searches directory and it's subdirectories for all files, which "*" stands for
          'Say for example you only want to search for jpeg files... then change "*" to "*.jpg"  
        For Each filename As String In IO.Directory.GetFiles(directory, "*", IO.SearchOption.AllDirectories)

             'The next line of code gets only file extensions from searched directories and subdirectories
            Dim fName As String = IO.Path.GetExtension(filename)

            If fName = ".suo" Then
                
                'Skips to next iteration of Loop, ignoring files with .suo extension 
                Continue For

            Else
                If fName = ".ini" Then

                    'Skips to next iteration of Loop, ignoring files with .ini extension
                    Continue For

                Else

                    'Kill function deletes all files in target directory and it's subdirectories 
                    'except for files with the .suo and .ini extension
                    System.IO.File.Delete(directory & fName)

                    'The below counter only displays the final count after all files have been processed
                    i = i + 1
                    TextBox1.Text = Convert.ToString(i)

                End If
            End If
        Next
    End Sub
End Class
```


You could also use the code without the If Then Statements. The .sou and .ini files gave me trouble because my Else event was complex. The following code might also delete those extensions:



```
Option Strict On

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim i as integer = 0

         'Target Directory
        Dim directory = "C:\Users\Peter\Desktop\TestFolder\"

          'Searches directory and it's subdirectories for all files, which "*" stands for
          'Say for example you only want to search for jpeg files... then change "*" to "*.jpg"  
        For Each filename As String In IO.Directory.GetFiles(directory, "*", IO.SearchOption.AllDirectories)

                    'Kill function deletes all files in target directory and it's subdirectories 
                    System.IO.File.Delete(directory & fName)

                    'The below counter only displays the final count after all files have been processed
                    i = i + 1
                    TextBox1.Text = Convert.ToString(i)
           
        Next
    End Sub
End Class
```

----------


## Peter Porter

I've changed the fName array GetExtension to GetFilename. The If Then statements now show the file names to ignore, backup.txt and log.txt:



```
Option Strict On

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim i as integer = 0

         'Target Directory
        Dim directory = "C:\Users\Peter\Desktop\TestFolder\"

          'Searches directory and it's subdirectories for all files, which "*" stands for
          'Say for example you only want to search for jpeg files... then change "*" to "*.jpg"
        For Each filename As String In IO.Directory.GetFiles(directory, "*", IO.SearchOption.AllDirectories)

             'The next line of code gets file names with extensions from searched directories and subdirectories
            Dim fName As String = IO.Path.GetFileName(filename)

            If fName = "backup.txt" Then
                
                'Skips to next iteration of Loop, ignoring backup files with the txt extension 
                Continue For

            Else
                If fName = "log.txt" Then

                    'Skips to next iteration of Loop, ignoring log files with the txt extension
                    Continue For

                Else

                    'Deletes all files in target directory and it's subdirectories 
                    'except for the backup.txt and log.txt files
                    System.IO.File.Delete(directory & fName)

                    'The below counter only displays the final count after all files have been processed
                    i = i + 1
                    TextBox1.Text = Convert.ToString(i)

                End If
            End If
        Next
    End Sub
End Class
```

----------


## Isaac Laqudem

Peter, I just tried your code and it gives me an "access denied" error for certain directories, which breaks the for-next loop.  How can I ignore that particular directory and go on?

TIA...

----------


## ident

There are a few issues with your submission. There is no logic to check for a file type and then do nothing with it.


vb Code:
Option Strict On Public Class Form1     Private Sub Foo(ByVal directory As String)         For Each filename As String In IO.Directory.GetFiles(directory, "*", IO.SearchOption.AllDirectories)             Dim fName As String = IO.Path.GetExtension(filename)             If fName = ".suo" Then                 Continue For             Else                If fName = ".ini" Then                     Continue For                 Else                  End If            End If        Next    End SubEnd Class

fName is not exactly descriptive either, especially as it's not a name you are retrieving.


vb Code:
Option Strict On Public Class Form1     Private Sub Foo(ByVal directory As String)        For Each filename As String In IO.Directory.GetFiles(directory, "*", IO.SearchOption.AllDirectories)             Dim fileExtension As String = IO.Path.GetExtension(filename)             If fileExtension <> ".suo" OrElse fileExtension <> ".ini" Then                ' handle here            End If        Next    End Sub End Class

An alternative way using LINQ


vb Code:
Option Strict On Imports System.IO Public Class Form1     Private Sub Foo(ByVal path As String)        Dim files = Directory.GetFiles(path).Where(Function(f) GetExtension(f) <> ".suo" OrElse GetExtension(f) <> ".ini").ToArray         Me.TextBox1.Text = files.Count.ToString         For Each currentFile In files            ' handle here        Next    End Sub     Private Function GetExtension(ByVal file As String) As String        Return Path.GetExtension(file)    End Function End Class


If we are going to be using LINQ it feels better suited using EnumerateFiles.

_The EnumerateFiles and GetFiles methods differ as follows: When you use EnumerateFiles, you can start enumerating the collection of names before the whole collection is returned; when you use GetFiles,  you must wait for the whole array of names to be returned before you  can access the array. Therefore, when you are working with many files  and directories, EnumerateFiles can be more efficient._


vb Code:
Option Strict On Imports System.IO Public Class Form1     Private Sub Foo(ByVal path As String)        For Each currentFile In Directory _            .GetFiles(path, "*", SearchOption.AllDirectories) _            .Where(Function(f) GetExtension(f) <> ".suo" OrElse GetExtension(f) <> ".ini")             ' do what ever         Next    End Sub     Private Function GetExtension(ByVal file As String) As String        Return Path.GetExtension(file)    End Function End Class

Finally dont be using KILL, it is a carry on from even way back as D.O.S, use net methods such as io.file.delete method.

----------


## Young Padawan

I have been trying to write this code for a little while now.. I need it to take a users search criteria and show the folder or files in an windows explorer window. Any Help

----------


## tfmiltz

Oh Peter Porter how I wish there was a warning on that codeblock heh.

I was scrolling down and saw the Kill for every item in directories - well most every

I do realize it's source for this task

but- considering the consequences? Maybe we should add a warning?

Since that code will wipe your drive from what I see

I'd comment out the kill line maybe.

Anyway heh-  what can I say- YIKES.

Tim Miltz

----------


## Peter Porter

Hi, tfmiltz.

I wrote this back in 2013 when I was a newbie to coding. Corrected...  :Smilie:

----------


## Peter Porter

ident, I know this thread is old, but thanks for the tips!

----------


## passel

Well, the thread is even older now, but I came across it while searching and since I haven't really used LINQ I was examining ident's code to see if I could understand just what it was doing, in particular the "Where" extension function.


```
            .Where(Function(f) GetExtension(f) <> ".suo" OrElse GetExtension(f) <> ".ini")
```

I gathered from the thread that Peter's code was to skip processing .suo and .ini files, but ident was using the OrElse (essentially Or operation).
Using Or to me would seem wrong, i.e. 
If the file ended in .suo, then the second expression would be True (the file wouldn't end in .ini) so the conditional code would be executed.
Likewise, if the file ended in .ini, then the first expression (it doesn't end with .suo) would be true so the conditional code would be executed.

So the filter isn't really filtering any files. The only way it could filter a file is if it ended with both .ini and .suo which isn't possible.
I did a quick test to confirm the .ini and .suo files did get processed along with all other files in the directory.

The condition needs to be And (i.e. AndAlso for the short circuit version). We want to process the file if it isn't a .suo file and it isn't a .ini file.


```
        .Where(Function(f) GetExtension(f) <> ".suo" AndAlso GetExtension(f) <> ".ini")
```

That will filter both .suo files and .ini files from being processed.

----------

