See MSDN samples with EnumerateDirectories & EnumerateFiles how-to-enumerate-directories-and-files
How do I get all file paths from folder and subfolders?
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?
- DESKTOP: Successful - 5484 ListBox items!
- DOCUMENTS: Not succesful - 0 ListBox items - Empty ListBox?
- DOCUMENTS-SUBFOLDERS: Successful - Clicking
on almost any subfolder in the Documents folder
gets the subfolder contents including files in
its subfolders! - DOWNLOADS: Successful - 148 ListBox items!
- MUSIC: Successful - 1 ListBox item!
- PICTURES: Successful - 482 ListBox items!
- VIDEOS: Successful - 2 ListBox items!
- LOCAL DISK (c:): Not Successful - 0 ListBox items - Empty ListBox?
- LOCAL DISK (c:) SUBFOLDERS: Successful - Almost all
subfolders with their subfolders and files! - PROGRAM FILES: Not Successful - 0 ListBox items - Empty ListBox?
- PROGRAM FILES SUBFOLDERS: Successful - Almost all
subfolders with their subfolders and files! - WINDOWS FOLDER: Not Successful - 0 ListBox items - Empty ListBox?
- WINDOWS SUBFOLDERS: Successful - Almost all
subfolders with their subfolders and files! - SYSTEM32: Not Successful - 0 Listbox items - Empty ListBox?
- SYSTEM32 SUBFOLDERS: Successful - Almost all
subfolders with their subfolders and files! - SYSWOW: Not Successful - 0 Listbox items - Empty ListBox?
- SYSWOW SUBFOLDERS: Successful - Almost all
subfolders with their subfolders and files! - DRIVE E: Not Successful - Interface freezes for a while then produces
no results - i.e. Empty ListBox? - 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?
- PROGRAM FILES: Not Successful - 0 ListBox Items - Empty ListBox?
- 7-ZIP (SUBFOLDER): Successful - 4 ListBox Items!
- ADOBE (SUBFOLDER): Successful - 95 ListBox Items! Only 4 execs are necessary!
- GOOGLE (SUBFOLDER): Successful - 7 ListBox Items! Only 1 exec is necessary!
- 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
- 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
2 answers
Sort by: Most helpful
-
-
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)