How do I get all file paths from folder and subfolders?

John Wilkinson 1 Reputation point
2022-09-20T21:54:35.307+00:00

243164-screenshot-1-desktop.png

Hi, this might seem like a repeat question but I have literally been searching for days through everything I can find and trying example code from websites. But each code I try gives me the same results? I just tested the following code from Microsoft and I get the same result? Can anyone help me to understand what I need to do to get some code working in the way I'm trying to achieve?

Article: Directory.EnumerateFiles Method

system.io.directory.enumeratefiles

Imports System.IO  
Imports System.Xml.Linq  

Module Module1  


    Sub Main()  
        Try  
            Dim docPath As String = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)  
            Dim files = From chkFile In Directory.EnumerateFiles(docPath, "*.txt", SearchOption.AllDirectories)  
                        From line In File.ReadLines(chkFile)  
                        Where line.Contains("Microsoft")  
                        Select New With {.curFile = chkFile, .curLine = line}  

            For Each f In files  
                Console.WriteLine($"{f.File}\t{f.Line}")  
            Next  
            Console.WriteLine($"{files.Count} files found.")  
        Catch uAEx As UnauthorizedAccessException  
            Console.WriteLine(uAEx.Message)  
        Catch pathEx As PathTooLongException  
            Console.WriteLine(pathEx.Message)  
        End Try  
    End Sub  
End Module  

Bugs:

The f.File and f.Line statements were red-underlined in the code and intelisense suggested changing these to cufFile. I tried that and the result is below.

Result:

System.UnauthorizedAccessException: 'Access to the path 'C:\Users\username\Documents\My Music' is denied.'

What I'm Trying To Do

I am working on a WIN10 PRO system, VB.NET, Visual Studio 2019.

I am attempting to get a list of file paths from folders and subfolders and insert these file paths into a ListBox or ListView. By itself, this is a simple task which I have already got several working examples. But the problem comes with the type of file and the location. One task I want to do, for example, is get a list of all executable file paths for installed programs/apps from which I can extract the icons and also run the programs. But when I attempt to do this using the AllDirectories flag I get the above access denied exception. For example, if I try to get a list of file paths directly from C:\ I get an exception denying access to the Recycle Bin? I have also tried accessing folders such as Program Files, System32 and sysWow, but I get the same kind of access to the path denied exception? If I could learn how to code to be able to extract the file paths (i.e. *.exe) then I could use this code to populate a ListBox or a ListView, extract the icons and run the programs directly from the paths in the ListBox or ListView. I have actually achieved this manually, but I don't think all that work is very user friendly. I hope this is clear?

Code I'm Using

I managed to get this code working roughly to access some Directories and mostly subfolders of Directories as can be seen in the AFTER CODE CHANGES section!

'CLEAR LBX ITEMS:  
        ListBox1.Items.Clear()  

        If fbd.ShowDialog = DialogResult.OK Then  

            Try  
                Dim a() As String  
                Dim sFolder As String = fbd.SelectedPath  

                a = IO.Directory.GetFiles(sFolder, "*.exe", IO.SearchOption.AllDirectories)  

                For Each sFolder In a  

                    'Console.WriteLine(sFolder.ToString)  
                    ListBox1.Items.Add(sFolder.ToString)  

                Next  

            Catch ex As UnauthorizedAccessException  
                Console.WriteLine(ex)  
            End Try  

        End If  

        'LBX ITEMS TOTAL:  
        Label2.Text = ListBox1.Items.Count.ToString  

EXCEPTIONS:

1. DESKTOP - WORKS! NO EXCEPTIONS!  
2. DOCUMENTS - System.UnauthorizedAccessException: 'Access to the path 'C:\Users\jmwil\Documents\My Music' is denied.'  
3. c:\ - System.UnauthorizedAccessException: 'Access to the path 'C:\$Recycle.Bin\S-1-5-18' is denied.'  
4. PROGRAM FILES - System.UnauthorizedAccessException: 'Access to the path 'C:\Program Files\Windows Defender Advanced Threat Protection\Classification\Configuration' is denied.'  
5. SYSTEM32 - System.UnauthorizedAccessException: 'Access to the path 'C:\Windows\System32\Com\dmp' is denied.'  
6. SysWOW64 - System.UnauthorizedAccessException: 'Access to the path 'C:\Windows\SysWOW64\Com\dmp' is denied.'  

AFTER CODE CHANGES

After changing the code (above) I got a bit more success. However, I still cannot achieve my goal? Some Directories yield folders, subfolders and files. Whilst others yield nothing unless I click on each subfolder to obtain its files and files from its subfolders? For example, clicking on Program Files yields nothing? But clicking on a subfolder yields its contents. So, how do I get a list of all the exec files for installed programs?

  1. DESKTOP: Successful - 5484 ListBox items!
  2. DOCUMENTS: Not succesful - 0 ListBox items - Empty ListBox?
  3. DOCUMENTS-SUBFOLDERS: Successful - Clicking
    on almost any subfolder in the Documents folder
    gets the subfolder contents including files in
    its subfolders!
  4. DOWNLOADS: Successful - 148 ListBox items!
  5. MUSIC: Successful - 1 ListBox item!
  6. PICTURES: Successful - 482 ListBox items!
  7. VIDEOS: Successful - 2 ListBox items!
  8. LOCAL DISK (c:): Not Successful - 0 ListBox items - Empty ListBox?
  9. LOCAL DISK (c:) SUBFOLDERS: Successful - Almost all
    subfolders with their subfolders and files!
  10. PROGRAM FILES: Not Successful - 0 ListBox items - Empty ListBox?
  11. PROGRAM FILES SUBFOLDERS: Successful - Almost all
    subfolders with their subfolders and files!
  12. WINDOWS FOLDER: Not Successful - 0 ListBox items - Empty ListBox?
  13. WINDOWS SUBFOLDERS: Successful - Almost all
    subfolders with their subfolders and files!
  14. SYSTEM32: Not Successful - 0 Listbox items - Empty ListBox?
  15. SYSTEM32 SUBFOLDERS: Successful - Almost all
    subfolders with their subfolders and files!
  16. SYSWOW: Not Successful - 0 Listbox items - Empty ListBox?
  17. SYSWOW SUBFOLDERS: Successful - Almost all
    subfolders with their subfolders and files!
  18. DRIVE E: Not Successful - Interface freezes for a while then produces
    no results - i.e. Empty ListBox?
  19. DRIVE E SUBFOLDERS: Successful - All subfolders I tried showed their
    subfolders and files.

CHANGED FILE SEARCH OPTION FROM . TO *.exe:

I don't need all the exec files. Just the ones related to the startup path of each installed program?

  1. PROGRAM FILES: Not Successful - 0 ListBox Items - Empty ListBox?
  2. 7-ZIP (SUBFOLDER): Successful - 4 ListBox Items!
  3. ADOBE (SUBFOLDER): Successful - 95 ListBox Items! Only 4 execs are necessary!
  4. GOOGLE (SUBFOLDER): Successful - 7 ListBox Items! Only 1 exec is necessary!
  5. IEXPLORE (SUBFOLDER): Successful - 5 ListBox Items! Only 1 exec is necessary!

SUGGESTED CODE RESULTS:

MS CODE - LAST EXAMPLE:

Tried the code to Access Documents, but it threw the following exception.
Also tried to access Desktop, but the result was exactly the same?

On line:

For Each fi In di.EnumerateFiles("*", SearchOption.AllDirectories)  

Gives the following exception:

System.UnauthorizedAccessException: 'Access to the path 'C:\Users\username\Documents\My Music' is denied.'  

Changed the special folder in the code to Program Files which threw the following exception:

On line:

Next (i.e. second Try Catch block)  

Threw Exception:

System.UnauthorizedAccessException: 'Access to the path 'C:\Program Files (x86)\Google\CrashReports' is denied.'  

Tried altering the special folder to Desktop and also changed the file size from files larger than 10MB to just

  1. This is the only directory which I could get to work without throwing an exception?

Tried changing the special folder to fbd.SelectedPath, but this threw the following exception:

System.InvalidCastException: 'Conversion from string "C:\Users\username\Desktop" to type 'Integer' is not valid.'  
System.InvalidCastException: 'Conversion from string "C:\Users\username\Desktop\BIBLE STU" to type 'Integer' is not valid.'  

Any help would be greatly appreciated! If you are able to give a simple code example it would greatly help me to learn!

Windows for business | Windows Client for IT Pros | User experience | Other
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Castorix31 90,686 Reputation points
    2022-09-20T22:16:27.38+00:00

    See MSDN samples with EnumerateDirectories & EnumerateFiles how-to-enumerate-directories-and-files


  2. Castorix31 90,686 Reputation points
    2022-09-22T23:03:46.86+00:00

    Add the dotnet-visual-basic tag or it is off-topic...

    A sample using Shell interfaces to display Applications folder :

            Dim GUID_IShellItem As Guid = GetType(IShellItem).GUID  
            Dim psi As IntPtr = IntPtr.Zero  
            Dim hr As HRESULT = SHCreateItemFromParsingName("shell:::{4234d49b-0245-4df3-b780-3893943456e1}", IntPtr.Zero, GUID_IShellItem, psi)  
            If (hr = HRESULT.S_OK) Then  
                Dim pShellItem As IShellItem = CType(Marshal.GetObjectForIUnknown(psi), IShellItem)  
                Dim BHID_EnumItems As New Guid("94f60519-2850-4924-aa5a-d15e84868039")  
                Dim pEnumItemsPtr As IntPtr = IntPtr.Zero  
                hr = pShellItem.BindToHandler(IntPtr.Zero, BHID_EnumItems, GetType(IEnumShellItems).GUID, pEnumItemsPtr)  
                If (hr = HRESULT.S_OK) Then  
                    Dim pEnumShellItems As IEnumShellItems = CType(Marshal.GetObjectForIUnknown(pEnumItemsPtr), IEnumShellItems)  
                    Dim nFetched As UInteger = 0  
                    Dim pShellItem2 As IShellItem = Nothing  
                    Dim nCpt = 1  
                    While ((HRESULT.S_OK = pEnumShellItems.Next(1, pShellItem2, nFetched)) AndAlso (nFetched = 1))  
                        Dim sbDisplayName As Text.StringBuilder = New Text.StringBuilder(260)  
                        hr = pShellItem2.GetDisplayName(SIGDN.SIGDN_NORMALDISPLAY, sbDisplayName)  
                        Dim pStorePtr As IntPtr = IntPtr.Zero  
                        Dim BHID_PropertyStore As New Guid("0384e1a4-1523-439c-a4c8-ab911052f586")  
                        hr = pShellItem2.BindToHandler(IntPtr.Zero, BHID_PropertyStore, GetType(IPropertyStore).GUID, pStorePtr)  
                        If (hr = HRESULT.S_OK) Then  
                            Dim pStore As IPropertyStore = CType(Marshal.GetObjectForIUnknown(pStorePtr), IPropertyStore)  
                            Dim nCount As UInteger = 0  
                            pStore.GetCount(nCount)  
                            For i As Integer = 0 To nCount - 1  
                                Dim pk As PROPERTYKEY  
                                hr = pStore.GetAt(i, pk)  
                                If (hr = HRESULT.S_OK) Then  
                                    Dim sbPropKeyName As System.Text.StringBuilder = New System.Text.StringBuilder(256)  
                                    hr = PSGetNameFromPropertyKey(pk, sbPropKeyName)  
                                    If (sbPropKeyName.ToString() = "System.Link.TargetParsingPath") Then  
                                        Dim pvValue As PROPVARIANT = New PROPVARIANT()  
                                        hr = pStore.GetValue(pk, pvValue)  
                                        If (hr = HRESULT.S_OK) Then  
                                            Dim sbValue As System.Text.StringBuilder = New System.Text.StringBuilder(1024)  
                                            hr = PropVariantToString(pvValue, sbValue, CUInt(sbValue.Capacity))  
                                            Dim sValue As String = sbValue.ToString()  
                                            Dim sExtension = Path.GetExtension(sValue)  
                                            If (sExtension = ".exe") Then  
                                                Dim pvValueArguments As PROPVARIANT = New PROPVARIANT()  
                                                hr = pStore.GetValue(PKEY_Link_Arguments, pvValueArguments)  
                                                Dim sbValueArguments As System.Text.StringBuilder = New System.Text.StringBuilder(1024)  
                                                hr = PropVariantToString(pvValueArguments, sbValueArguments, CUInt(sbValueArguments.Capacity))  
                                                Dim sValueArguments As String = sbValueArguments.ToString()  
                                                Console.WriteLine(String.Format("Application n° {0}", nCpt.ToString()))  
                                                Console.WriteLine(String.Format(vbTab + "Name : {0}", sbDisplayName.ToString()))  
                                                Console.WriteLine(String.Format(vbTab + "Executable : {0}", sValue))  
                                                If (sValueArguments <> "") Then  
                                                    Console.WriteLine(String.Format(vbTab + "Arguments : {0}", sValueArguments))  
                                                End If  
                                                nCpt += 1  
                                                Exit For  
                                            End If  
                                        End If  
                                    End If  
                                    If (sbPropKeyName.ToString() = "System.AppUserModel.PackageInstallPath") Then  
                                        Dim pvValue As PROPVARIANT = New PROPVARIANT()  
                                        hr = pStore.GetValue(pk, pvValue)  
                                        If (hr = HRESULT.S_OK) Then  
                                            Dim sbValue As System.Text.StringBuilder = New System.Text.StringBuilder(1024)  
                                            hr = PropVariantToString(pvValue, sbValue, CUInt(sbValue.Capacity))  
                                            Dim sValue As String = sbValue.ToString()  
                                            Console.WriteLine(String.Format("Application n° {0}", nCpt.ToString()))  
                                            Console.WriteLine(String.Format(vbTab + "Name : {0}", sbDisplayName.ToString()))  
                                            Console.WriteLine(String.Format(vbTab + "PackageInstallPath : {0}", sValue))  
                                        End If  
                                    End If  
                                    If (sbPropKeyName.ToString() = "System.AppUserModel.PackageFullName") Then  
                                        Dim pvValue As PROPVARIANT = New PROPVARIANT()  
                                        hr = pStore.GetValue(pk, pvValue)  
                                        If (hr = HRESULT.S_OK) Then  
                                            Dim sbValue As System.Text.StringBuilder = New System.Text.StringBuilder(1024)  
                                            hr = PropVariantToString(pvValue, sbValue, CUInt(sbValue.Capacity))  
                                            Dim sValue As String = sbValue.ToString()  
                                            Console.WriteLine(String.Format(vbTab + "PackageFullName : {0}", sValue))  
                                            nCpt += 1  
                                            Exit For  
                                        End If  
                                    End If  
                                End If  
                            Next  
                            Marshal.ReleaseComObject(pStore)  
                        End If  
                    End While  
                    Marshal.ReleaseComObject(pShellItem2)  
                    Marshal.Release(pEnumItemsPtr)  
                End If  
                Marshal.ReleaseComObject(pShellItem)  
            End If  
    

    with declarations :

        Public Enum HRESULT As Integer  
        S_OK = 0  
        S_FALSE = 1  
        E_NOINTERFACE = &H80004002  
        E_NOTIMPL = &H80004001  
        E_FAIL = &H80004005  
        E_UNEXPECTED = &H8000FFFF  
    End Enum  
    
    <ComImport()>  
    <InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>  
    <Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE")>  
    Public Interface IShellItem  
        <PreserveSig()>  
        Function BindToHandler(ByVal pbc As IntPtr, ByRef bhid As Guid, ByRef riid As Guid, ByRef ppv As IntPtr) As HRESULT  
        Function GetParent(ByRef ppsi As IShellItem) As HRESULT  
        Function GetDisplayName(ByVal sigdnName As SIGDN, ByRef ppszName As System.Text.StringBuilder) As HRESULT  
        Function GetAttributes(ByVal sfgaoMask As UInteger, ByRef psfgaoAttribs As UInteger) As HRESULT  
        Function Compare(ByVal psi As IShellItem, ByVal hint As UInteger, ByRef piOrder As Integer) As HRESULT  
    End Interface  
    
    Public Enum SIGDN As Integer  
        SIGDN_NORMALDISPLAY = &H0  
        SIGDN_PARENTRELATIVEPARSING = &H80018001  
        SIGDN_DESKTOPABSOLUTEPARSING = &H80028000  
        SIGDN_PARENTRELATIVEEDITING = &H80031001  
        SIGDN_DESKTOPABSOLUTEEDITING = &H8004C000  
        SIGDN_FILESYSPATH = &H80058000  
        SIGDN_URL = &H80068000  
        SIGDN_PARENTRELATIVEFORADDRESSBAR = &H8007C001  
        SIGDN_PARENTRELATIVE = &H80080001  
    End Enum  
    
    <ComImport(),  
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown),  
    Guid("70629033-e363-4a28-a567-0db78006e6d7")>  
    Public Interface IEnumShellItems  
        <PreserveSig()>  
        Function [Next](ByVal celt As UInteger, ByRef rgelt As IShellItem, ByRef pceltFetched As UInteger) As HRESULT  
        Function Skip(ByVal celt As UInteger) As HRESULT  
        Function Reset() As HRESULT  
        Function Clone(ByRef ppenum As IEnumShellItems) As HRESULT  
    End Interface  
    
    <DllImport("Shell32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>  
    Public Shared Function SHCreateItemFromParsingName(pszPath As String, pbc As IntPtr, ByRef riid As Guid, ByRef ppv As IntPtr) As HRESULT  
    End Function  
    
    <DllImport("Propsys.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>  
    Public Shared Function PSGetNameFromPropertyKey(ByRef propkey As PROPERTYKEY, ByRef ppszCanonicalName As System.Text.StringBuilder) As HRESULT  
    End Function  
    
    <DllImport("Propsys.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>  
    Public Shared Function PropVariantToString(ByRef propvar As PROPVARIANT, psz As System.Text.StringBuilder, cch As UInteger) As HRESULT  
    End Function  
    
    <ComImport, Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>  
    Interface IPropertyStore  
        Function GetCount(<Out> ByRef propertyCount As UInteger) As HRESULT  
        Function GetAt(<[In]> propertyIndex As UInteger, <Out, MarshalAs(UnmanagedType.Struct)> ByRef key As PROPERTYKEY) As HRESULT  
        Function GetValue(<[In], MarshalAs(UnmanagedType.Struct)> ByRef key As PROPERTYKEY, <Out, MarshalAs(UnmanagedType.Struct)> ByRef pv As PROPVARIANT) As HRESULT  
        Function SetValue(<[In], MarshalAs(UnmanagedType.Struct)> ByRef key As PROPERTYKEY, <[In], MarshalAs(UnmanagedType.Struct)> ByRef pv As PROPVARIANT) As HRESULT  
        Function Commit() As HRESULT  
    End Interface  
    
    <StructLayout(LayoutKind.Sequential, Pack:=4)>  
    Public Structure PROPERTYKEY  
        Private fmtid As Guid  
        Private pid As Integer  
    
        Public ReadOnly Property FormatId As Guid  
            Get  
                Return Me.fmtid  
            End Get  
        End Property  
    
        Public ReadOnly Property PropertyId As Integer  
            Get  
                Return Me.pid  
            End Get  
        End Property  
    
        Public Sub New(formatId As Guid, propertyId As Integer)  
            Me.fmtid = formatId  
            Me.pid = propertyId  
        End Sub  
    End Structure  
    
    <StructLayout(LayoutKind.Sequential)>  
    Public Structure PROPARRAY  
        Public cElems As UInteger  
        Public pElems As IntPtr  
    End Structure  
    
    <StructLayout(LayoutKind.Explicit, Pack:=1)>  
    Public Structure PROPVARIANT  
        <FieldOffset(0)>  
        Public varType As UShort  
        <FieldOffset(2)>  
        Public wReserved1 As UShort  
        <FieldOffset(4)>  
        Public wReserved2 As UShort  
        <FieldOffset(6)>  
        Public wReserved3 As UShort  
        <FieldOffset(8)>  
        Public bVal As Byte  
        <FieldOffset(8)>  
        Public cVal As SByte  
        <FieldOffset(8)>  
        Public uiVal As UShort  
        <FieldOffset(8)>  
        Public iVal As Short  
        <FieldOffset(8)>  
        Public uintVal As UInt32  
        <FieldOffset(8)>  
        Public intVal As Int32  
        <FieldOffset(8)>  
        Public ulVal As UInt64  
        <FieldOffset(8)>  
        Public lVal As Int64  
        <FieldOffset(8)>  
        Public fltVal As Single  
        <FieldOffset(8)>  
        Public dblVal As Double  
        <FieldOffset(8)>  
        Public boolVal As Short  
        <FieldOffset(8)>  
        Public pclsidVal As IntPtr  
        <FieldOffset(8)>  
        Public pszVal As IntPtr  
        <FieldOffset(8)>  
        Public pwszVal As IntPtr  
        <FieldOffset(8)>  
        Public punkVal As IntPtr  
        <FieldOffset(8)>  
        Public ca As PROPARRAY  
        <FieldOffset(8)>  
        Public filetime As System.Runtime.InteropServices.ComTypes.FILETIME  
    End Structure  
    
    Public Shared ReadOnly PKEY_Link_TargetParsingPath As PROPERTYKEY = New PROPERTYKEY(New Guid("B9B4B3FC-2B51-4A42-B5D8-324146AFCF25"), 2)  
    Public Shared ReadOnly PKEY_Link_Arguments As PROPERTYKEY = New PROPERTYKEY(New Guid("436F2667-14E2-4FEB-B30A-146C53B5B674"), 100)  
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.