Access to files with long paths (over 260)

I use Microsoft Scripting Runtime (FSO) to parse folders and create a list of all content, folders are online, and the resulting paths end longer than 260. The minimum code I have is the following: -

Private Sub ProcessFolder(ByVal StrFolder As String) Dim Fl As File Dim Fldr As Folder Dim RootFldr As Folder Set RootFldr = FS.GetFolder(StrFolder) For Each Fl In RootFldr.Files Debug.Print Fl.Path Next For Each Fldr In RootFldr.SubFolders DoEvents ProcessFolder Fldr.Path Next Set RootFldr = nothing End sub 

At a certain level of StrFolder length became 259, the Set RootFldr ... pattern string worked, but For Each Fl In RootFldr.Files error 76: Path not found , presumably because the content forces the path to break the 260 limit.

In Windows Explorer, there were files in the folder. I use Excel as the host for this code, since I output the result to workbooks.

To be very clear on my question and its background, I need to use FSO (happy to be shown alternatives, if they exist) to access files that are more than 260 characters deep in my network path. I need this as an FSO, since the tool I have is a folder path and file paths, name, size and change.

+7
vba excel filesystemobject fso
source share
3 answers

This required a bit of creative coding, but using ShortPath was the answer.

This tool is designed to create a list of each folder and file in the root folder, files also showing their size, and created / changed dates. The problem was that the resulting path to the file or folder was more than 260, then Error 76: Path Not Found error was selected, and the code would not capture the contents of this area.

Using Microsoft Scripting Runtime (FSO) ShortPath will circumvent this problem, but the path went from a person readable to coding: -

Full path \\ServerName00000\Root_Root_contentmanagement\DPT\STANDARDS_GUIDELINES\VENDOR_CERTIFICATION_FILES\PDFX_CERTIFICATION_ALL\2006_2007\DPT\CompantName0\Approved\Quark\India under Colonial Rule_structure sample\058231738X\Douglas M. Peers_01_058231738X\SUPPORT\ADDITIONAL INFORMATION\IUC-XTG & XML file \ VENDOR_CERTIFICATION_FILES \ PDFX_CERTIFICATION_ALL \ 2006_2007 \ DPT \ CompantName0 \ Approved \ Quark \ India under Colonial Rule_structure sample \ 058231738X \ Douglas M. Peers_01_058231738X \ SUPPORT \ ADDITIONAL INFORMATION \ IUC-XTG & XML file

\\lo3uppesaapp001\pesa_cmcoe_contentmanagement\CTS\S4SJ05~5\V275SE~8\PDM5D9~G\2N52EQ~5\HPE\GS9C6L~U\Approved\Quark\IQPSJ5~F\0CWHH1~G\DOFNHA~8\SUPPORT\A6NO7S~K\IUC-XTG & XML file

(Note. I changed the full path to protect IP and company information, but the size is the same)

You can see when I could go a short way to someone, and they could put him in Windows Explorer to get there, they would know where this is happening, just looking to get around this, using a global variable that stored the path folder as a full line and followed what the short path was doing. this line is what I output to the user. The code below is shortened, but shows how I achieved it.

FSO's ShortPath short answer goes past the problem, but the path will not be enough.

 Dim FS As New FileSystemObject Dim LngRow As Long Dim StrFolderPath As String Dim WkBk As Excel.Workbook Dim WkSht As Excel.Worksheet Public Sub Run_Master() Set WkBk = Application.Workbooks.Add WkBk.SaveAs ThisWorkbook.Path & "\Data.xlsx" Set WkSht = WkBk.Worksheets(1) WkSht.Range("A1") = "Path" WkSht.Range("B1") = "File Name" WkSht.Range("C1") = "Size (KB)" WkSht.Range("D1") = "Created" WkSht.Range("E1") = "Modified" LngRow = 2 Run "\\ServerName00000\AREA_DEPT0_TASK000" Set WkSht = Nothing WkBk.Close 1 Set WkBk = Nothing MsgBox "Done!" End Sub Private Sub Run(ByVal StrVolumeToCheck As String) Dim Fldr As Folder Dim Fldr2 As Folder Set Fldr = FS.GetFolder(StrVolumeToCheck) 'This is the variable that follows the full path name StrFolderPath = Fldr.Path WkSht.Range("A" & LngRow) = StrFolderPath LngRow = LngRow +1 For Each Fldr2 In Fldr.SubFolders If (Left(Fldr2.Name, 1) <> ".") And (UCase(Trim(Fldr2.Name)) <> "LOST+FOUND") Then ProcessFolder Fldr2.Path End If Next Set Fldr = Nothing End Sub Private Sub ProcessFolder(ByVal StrFolder As String) 'This is the one that will will be called recursively to list all files and folders Dim Fls As Files Dim Fl As File Dim Fldrs As Folders Dim Fldr As Folder Dim RootFldr As Folder Set RootFldr = FS.GetFolder(StrFolder) If (RootFldr.Name <> "lost+found") And (Left(RootFldr.Name, 1) <> ".") Then 'Add to my full folder path StrFolderPath = StrFolderPath & "\" & RootFldr.Name WkSht.Range("A" & LngRow) = StrFolderPath WkSht.Range("D1") = RootFldr.DateCreated WkSht.Range("E1") = RootFldr.DateLastModified Lngrow = LngRow + 1 'This uses the short path to get the files in FSO Set Fls = FS.GetFolder(RootFldr.ShortPath).Files For Each Fl In Fls 'This output our string variable of the path (ie not the short path) WkSht.Range("A" & LngRow) = StrFolderPath WkSht.Range("B" & LngRow) = Fl.Name WkSht.Range("C" & LngRow) = Fl.Size /1024 '(bytes to kilobytes) WkSht.Range("D" & LngRow) = Fl.DateCreated WkSht.Range("E" & LngRow) = Fl.DateLastModified LngRow = LngRow + 1 Next Set Fls = Nothing 'This uses the short path to get the sub-folders in FSO Set Fldrs = FS.GetFolder(RootFldr.ShortPath).SubFolders For Each Fldr In Fldrs 'Recurse this Proc ProcessFolder Fldr.Path DoEvents Next Set Fldrs = Nothing 'Now we have processed this folder, trim the folder name off of the string StrFolderPath = Left(StrFolderPath, Len(StrFolderPath) - Len(RootFldr.Name)+1) End If Set RootFldr = Nothing End Sub 

As already mentioned, this is an abridged version of the code that works for me to demonstrate the method used to overcome this limit. It actually seems pretty rudimentary as soon as I did this.

+3
source share

The method for converting MAXFILE encumbered DOS path names to host OS path names is well known and documented . Summarizing:

  • A path prefix that uses a drive letter with \\?\ , \\?\C:\foo\bar\baz.txt
  • The prefix of the path that uses the file share with '\\?\UNC\ , for example \\?\UNC\server\share\baz.txt .

It works well with FileSystemObject, at least when I tested your code on Windows 10. This may not be the case with older versions of Windows or with a network redirector on your server. Tested with the FAR file manager to create subdirectories with long names and with:

 Dim path = "\\?\C:\temp\LongNameTest" ProcessFolder path 

It is made:

 \\?\c:\temp\LongNameTest\VeryLongFolderName0123456789012345678901234567890123456789012345678901234567890123456789\VeryLongFolderName0123456789012345678901234567890123456789012345678901234567890123456789\VeryLongFolderName0123456789012345678901234567890123456789012345678901234567890123456789\VeryLongFolderName0123456789012345678901234567890123456789012345678901234567890123456789\VeryLongFolderName0123456789012345678901234567890123456789012345678901234567890123456789\Chrysanthemum.jpg 

Length 488 characters. What you need to remember:

  • The names of the native paths must be full paths, they cannot be relative paths. In other words, they should always start with the drive letter or common name and begin with the root of the drive / shared.
  • You return the name of the native path, do not forget to remove the prefix again if you display it.
  • Not verified, but should fail, yet the limit on the length of the file name itself (without directory names) cannot exceed 259 characters. It should not be a problem at all, as the user also cannot create them.
+7
source share

I walked around this once using the subst command of the shell command. It allows you to assign a drive letter to a local path (sort of like a network resource).

+2
source share

All Articles