访问具有长path的文件(超过260个)

我正在使用Microsoft Scripting Runtime(FSO)来parsing文件夹并生成其所有内容的列表,这些文件夹位于networking上,所产生的path最终长于260.我拥有的最小代码如下所示:

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 

在一定的级别StrFolder长度变为259, Set RootFldr ...文件夹行工作,但For Each Fl In RootFldr.Files给出的错误76: Path not found ,大概是因为内容导致path违反了260的限制。

在Windows资源pipe理器中查看文件夹中有文件。 我正在使用Excel作为此代码的主机,因为我将结果输出到工作簿。

只是要清楚我的问题和背景,我需要使用FSO(如果存在的话,很高兴能够看到替代品)来访问networkingpath深度超过260个字符的文件。 我需要它作为FSO作为我正在使用的文件夹path和文件path,名称,大小创build和修改。

将MAXFILE阻塞的DOSpath名称转换为本地操作系统path名称的技术已经很好地build立和logging了 。 总结:

  • \\?\C:\foo\bar\baz.txt前缀一个使用\\?\的驱动器盘符的path
  • 使用'\\?\UNC\\\?\UNC\server\share\baz.txt一样使用文件共享前缀。

至less当我在Windows 10上testing你的代码时,也可以和FileSystemObject一起使用。在旧版本的Windows或服务器上的networkingredirect器中,情况可能不一定如此。 通过使用FAR文件pipe理器来创build长名称的子目录并通过以下validation来testing:

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

制作:

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

这是488个字符长。 需要注意的是:

  • 本机path名称必须是完整path,它们不能是相对path。 换句话说,它们必须始终以驱动器号或共享名称开始,并从驱动器/共享的根目录开始。
  • 你得到本地path名称,不要忘记如果你显示它再次剥离前缀。
  • 没有testing,但应该失败,文件名本身(没有目录名称)的长度仍然有限​​制,不能超过259个字符。 应该不是一个问题,因为用户也不能创build它们。

这花了一点创意编码,但使用ShortPath是答案。

这个工具是创build一个根文件夹中的每个文件夹和文件的列表,这些文件也显示它们的大小,并创build/修改date。 问题是当一个文件或文件夹的结果path超过260,然后错误Error 76: Path Not Found ,代码将不会捕获该区域的内容。

使用Microsoft脚本运行时(FSO) ShortPath将解决此问题,但path从人类可ShortPath编码:

完整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

Short Path \\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

(注意我已经改变了保护IP和公司信息的完整path,但大小是一样的)

你可以看到,虽然我可以通过短path的人,他们可以把它放到Windows资源pipe理器到达那里,他们会知道知道在哪里去了,只是看看,解决这个使用全局variables,保持文件夹path为完整的string,并遵循短path正在做的事情。 这个string是我输出给用户的。 下面的代码被删减,但是显示了我是如何实现的。

简短的回答是FSO中的ShortPath将通过这个问题,但path不会很漂亮。

 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 

如前所述,这是一个正在为我工​​作的代码的一个缩减版本,用来举例说明用于超越这个限制的方法。 事实上,一旦我完成它似乎很简单。

我使用命令shell的subst命令来解决这个问题。 它允许您将驱动器号分配给本地path(类似于networking共享)。