我使用Microsoft Scripting Runtime(FSO)来解析文件夹并生成所有内容的列表,文件夹位于网络上,结果路径最终超过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
,可能是因为内容导致了违规路径260限制。
在Windows资源管理器中查找文件夹中有文件。我正在使用Excel作为此代码的主机,因为我将结果输出到工作簿。
为了清楚地了解我的问题及其背景,我需要使用FSO(很高兴能够显示替代品,如果它们存在)来访问网络路径深度超过260个字符的文件。我需要它作为FSO,因为我的工具是获取文件夹路径和文件路径,名称,大小创建和修改。
答案 0 :(得分:8)
将MAXFILE加密的DOS路径名转换为本机OS路径名的技术已经很好地建立and documented。总结:
\\?\
的驱动器号的前缀路径,例如\\?\C:\foo\bar\baz.txt
'\\?\UNC\
的{{1}}前缀使用文件共享的路径。也适用于FileSystemObject,至少当我在Windows 10上测试你的代码时。在旧的Windows版本或服务器上的网络重定向器中可能不一定如此。通过使用FAR文件管理器来创建具有长名称并通过以下方式验证的子目录进行测试:
\\?\UNC\server\share\baz.txt
制作人:
Dim path = "\\?\C:\temp\LongNameTest"
ProcessFolder path
长度为488个字符。要记住的事情:
答案 1 :(得分:3)
这需要一些创意编码,但使用ShortPath
就是答案。
此工具用于创建根文件夹中每个文件夹和文件的列表,这些文件还显示其大小以及创建/修改日期。问题是当文件或文件夹的结果路径超过260时,则抛出错误Error 76: Path Not Found
,代码将无法捕获该区域的内容。
使用Microsoft Scripting Runtime(FSO)ShortPath
可以解决这个问题,但路径从人类可读到编码: -
完整路径
\\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
短路径
\\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和公司信息的完整路径,但大小相同)
你可以看到,虽然我可以通过短路径到某人,他们可以把它放到Windows资源管理器中到达那里,他们会通过简单的查找知道它去了哪里,绕过这个使用了一个保存文件夹的全局变量路径作为一个完整的字符串,并遵循短路径正在做的事情。那么这个字符串就是我输出给用户的内容。下面的代码被删减,但显示了我是如何实现它的。
FSO中的简短答案是ShortPath
将会解决问题,但路径不会很漂亮。
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 (i.e. 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
如前所述,这是代码的剪切版本,它可以帮助我举例说明用于超出此限制的方法。一旦我完成它,实际上似乎很简陋。
答案 2 :(得分:2)
我使用命令shell的subst命令解决了这个问题。它允许您将驱动器号分配给本地路径(类似于网络共享)。