How to Deal with Files with a Name Longer Than 259 Characters

How to deal with files with a name longer than 259 characters?

.NET 4.6.2 Solution

Use the \\?\C:\Verrrrrrrrrrrry long path syntax as described here.

.NET Core Solution

It just works because the framework adds the long path syntax for you.

Pre .NET 4.6.2 Solution

Also use the long path syntax and the Unicode version of the Win32 API function with P/Invoke.
From Naming Files, Paths, and Namespaces:

The Windows API has many functions that also have Unicode versions to permit an extended-length path for a maximum total path length of 32,767 characters. This type of path is composed of components separated by backslashes, each up to the value returned in the lpMaximumComponentLength parameter of the GetVolumeInformation function (this value is commonly 255 characters). To specify an extended-length path, use the \\?\ prefix. For example, \\?\D:\very long path.

Reading this Microsoft Support page might also be interesting.

A very extensive explanation in Long Paths in .NET by Kim Hamilton at the BCL Team blog lists a few hitches in handling these paths which he claims are the reason this syntax is still not supported in .NET directly:

There are several reasons we were reluctant to add long paths in the past, and why we’re still careful about it <...>.

<...> the \\?\ prefix not only enables long paths; it causes the path to be passed to the file system with minimal modification by the Windows APIs. A consequence is that \\?\ turns off file name normalization performed by Windows APIs, including removing trailing spaces, expanding ‘.’ and ‘..’, converting relative paths into full paths, and so on.<...>

<...> Long paths with the \\?\ prefix can be used in most of the file-related Windows APIs, but not all Windows APIs. For example, LoadLibrary<...> fails if the file name is longer than MAX_PATH. <...> There are similar examples throughout the Windows APIs; some workarounds exist, but they are on a case-by-case basis.

Another factor <...> is compatibility with other Windows-based applications and the Windows shell itself <...>

Because this problem is becoming increasingly common <...> there are efforts throughout Microsoft to address it. In fact, as a timely Vista plug, you’ll notice a couple of changes that reduce the chance of hitting the MAX_PATH limit: many of the special folder names have shortened and, more interestingly, the shell is using an auto-path shrinking feature <...> to attempt to squeeze them into 260 characters.


Warning: You might need to call the Windows APIs directly, since I think the .NET Framework might not support this kind of path syntax.

Why can I open a file with a long ( 259 characters) path from a console app, but not from a PowerPoint VSTO add-in?

The simplest way is to use a config file for the host application (i.e. in this case, a file named POWERPNT.EXE.config, placed in the same directory as POWERPNT.EXE) with the following content:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=false;Switch.System.IO.BlockLongPaths=false" />
</runtime>
</configuration>

You can find possible solutions described in the How to deal with files with a name longer than 259 characters? thread.

How do I find files with a path length greater than 260 characters in Windows?

do a dir /s /b > out.txt and then add a guide at position 260

In powershell cmd /c dir /s /b |? {$_.length -gt 260}

Access files with long paths (over 260)

This took a little creative coding but the use of ShortPath was the answer.

This tool was to create a list of every folder and file in a root folder, the files also showing their size, and created/modified dates. The issue was when the resultant path of a file or folder was over 260, then the error Error 76: Path Not Found was thrown and the code would not capture the content of that area.

Using Microsoft Scripting Runtime (FSO) ShortPath would get around this issue but the path went from human readable to coded:-

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

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

(Note I've altered the full path to protect IP and company info but the size is the same)

You can see while I could pass short path to someone and they could put it into Windows Explorer to get there, they would know know where it went by simply looking, to get around this a used a global variable that kept the folder path as a full string and followed what the short path was doing. this string is then what I output to the user. The below code is cut down but shows how I achieved it.

The short answer is ShortPath in FSO will get past the issue but the path will not be pretty.

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

As mentioned this is a cut version of the code that is working for me to exemplify the the method used to get past this limit. Actually seems quite rudimentary once I'd done it.

Get Security Information of a too long file path above 260 characters: C#

I saw in some other posts that installing .NET Framework 4.6.2 does help. As the last resort, I tried it. I had Visual Studio 2015. I installed .NET Framework 4.6.2. It still did not work. Then I installed Visual Studio 2017 and chose .NET Framework 4.6.2. It did eliminate Path Too Long Exception. But it gave a new exception called Invalid name, Invalid parameter.

One of my colleague suggested me to check the value of registry

Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled

It's original value was 0. I set it to 1. And both the Path Too Long and Invalid Name, Invalid parameter exception were gone. I believe this registry key does not exist in computer that does not have .NET Framework 4.6.2.

Windows ShellExecuteW with filename that exceeds MAX_PATH (260 characters)

I read some cases, about this issue. Find this article:Long Paths in .NET, Part 1 of 3 [Kim Hamilton]

If you prefix the file name with "\?\" and call the Unicode versions of the Windows APIs, then you can use file names up to 32K characters in length. In other words, the \?\ prefix is a way to enable long paths while working with the Windows file APIs.

and:

Long paths with the \?\ prefix can be used in most of the file-related Windows APIs, but not all Windows APIs.

I also test ShellExcuteW with \\?\,it failed.
Working well with SHOpenFolderAndSelectItems

CoInitialize(NULL);

LPCWSTR file_name ;//Change the path according to your needs

PIDLIST_ABSOLUTE pidl;
if (SUCCEEDED(SHParseDisplayName(file_name, 0, &pidl, 0, 0)))
{
ITEMIDLIST idNull = { 0 };
LPCITEMIDLIST pidlNull[1] = { &idNull };
SHOpenFolderAndSelectItems(pidl, 1, pidlNull, 0);
ILFree(pidl);
}

Note:CoInitialize or CoInitializeEx must be called before using SHOpenFolderAndSelectItems. Not doing so causes SHOpenFolderAndSelectItems to fail.

Best way to resolve file path too long exception

As the cause of the error is obvious, here's some information that should help you solve the problem:

See this MS article about Naming Files, Paths, and Namespaces

Here's a quote from the link:

Maximum Path Length Limitation In the Windows API (with some exceptions discussed in the following paragraphs), the maximum length
for a path is MAX_PATH, which is defined as 260 characters. A local
path is structured in the following order: drive letter, colon,
backslash, name components separated by backslashes, and a terminating
null character. For example, the maximum path on drive D is "D:\some
256-character path string<NUL>" where "<NUL>" represents the invisible
terminating null character for the current system codepage. (The
characters < > are used here for visual clarity and cannot be part of
a valid path string.)

And a few workarounds (taken from the comments):

There are ways to solve the various problems. The basic idea of the solutions listed below is always the same: Reduce the path-length in order to have path-length + name-length < MAX_PATH. You may:

  • Share a subfolder
  • Use the commandline to assign a drive letter by means of SUBST
  • Use AddConnection under VB to assign a drive letter to a path


Related Topics



Leave a reply



Submit