Share via


.NET Troubleshooting: Path too Long Exception and .NET PowerShell Robocopy Clone

.NET Error: Path too Long

Since .NET 4.6.2 on Windows 10 there is a solution (see below)

Some of you may know the famous error “System.IO.PathTooLongException“.

The path is too long after being fully qualified. Make sure path is less than 260 characters.

This is by design from the Windows API and the .NET Framework.

Naming Files, Paths, and Namespaces: http://msdn.microsoft.com/en-us/library/aa365247.aspx

The Windows API Function CreateFileEx from the Kernel32.dll utilizes Unicode.  By appending the string "\?\ in front of the path, this API Function can handle up to 32,000 characters.

See: http://blogs.msdn.com/b/bclteam/archive/2007/02/13/long-paths-in-net-part-1-of-3-kim-hamilton.aspx

You can list long paths using the \?\c:\ syntax in cmd.exe!

dir \?\c:\ /s

PowerShell and cmd.exe:

$foldernames=cmd /c 'dir \?\c:\ /s /ad |findstr "\\?\"'

The prefix of \?\ is not supported within .Net at the time of writing (as of version 4.0).

So you can not simply append the string "\?\ to your normal Path! This will only work with the mentioned Windows API Function!

Otherwise, you will get the error "Illegal characters in path." !

You can try to use the .NET Classes System.IO.Directory.GetFiles() and System.IO.Directory.GetDirectories()

They both return back string arrays of the full path of the files and directories respectively.

As long as you don't need the additional properties, as in this case, this is the easiest solution to the problem.

See: http://aspadvice.com/blogs/davidwalker/archive/2007/01/22/PathTooLongException-work-around.aspx

If you can’t live with that, there is a Project on Codeplex from the .NET Base Class Library (BCL) Team.

The work there is in the conceptual state and there is no further development, but you can use it if you are a .NET Developer:

See: http://bcl.codeplex.com/releases/view/42783?ProjectName=bcl

Read the Blog Post of the BCL Team:

There is also a library that encapsulates all this work over at google code called zeta long paths

See: http://code.google.com/p/zetalongpaths/

NET 4.6.2 and long paths on Windows 10

Long paths aren't enabled by default yet. You need to set a policy to enable support.

To do this you want to "Edit group policy" in the Start search bar or run "gpedit.msc" from the Run command (Windows-R).

In the Local Group Policy Editor navigate to "Local Computer Policy: Computer Configuration: Administrative Templates: All Settings".

In this location, you can find "Enable Win32 long paths".

After you've turned this on you can fire up a new instance of PowerShell and free yourself from the constraints of MAX_PATH!

The key File and Directory Management APIs respect this and now allow you to skip the check for MAX_PATH without having to resort to using "\?\

This is also possible as PowerShell has opted into the new .NET path support (being that it is a .NET application).

In .NET 4.6.2 there will no longer throw PathTooLongException if a path is >= MAX_PATH.

If the OS doesn't like it we'll surface whatever the OS returns as an error (which may be PathTooLong)..

In many cases, the OS will return DirectoryNotFound for paths that are too long. The primary case is with creating files.

In .NET 4.6.2 there is no way to programmatically check whether paths are actually too long so there is no Translation between DirectoryNotFound into PathTooLong.

JeremyKuhne wrote Articles about this Topic:

Other .NET libraries which support long path

Extra Tip:

The original .NET classes for the file system are working very slow.

If you need more speed you have to use the following .NET libraries or use the Microsoft Robocopy.exe

QuickIO.NET

QuickIO.NET is a library to replace the file system classes of the .NET Framework, with nearly identical signatures of the native .NET methods.

QuickIO.NET focuses on performance and comfortable dealing with the file system.

In addition to the fast communication with the Win32 API and browsing the file system quickly and efficiently,

QuickIO.NET provides methods to read, write, edit, move, compress, split files and directories - and many many more.

Why QuickIO.NET is useful for you and your application much faster browsing of folder structures (up to 30x faster)

  • Lightning-fast retrieve of metadata of folders, files, and directory structures
  • File chunk support for reading, comparisons, and hashing.
  • Data transfer services monitored file and directory copy/move with progress events
  • Custom service and job support (via extensions and own implementation)
  • Long path support (UNC paths) up to 32767 characters
  • Calculate checksums of files and file chunks
  • Fully tested source code using UnitTests
  • Nearly identical signature of methods to native .NET
  • Async Operations (requires .NET 4.0 or above)
  • Multiple releases from .NET 2.0 to .NET 4.5
  • Well documented
  • Open Source License (MSPL)

More info

AlphaFS

AlphaFS is a .NET library providing more complete Win32 file system functionality to the .NET platform than the standard System.IO classes.

The file system support in .NET is pretty good for most uses. However, there are a few shortcomings, which this library tries to alleviate. The most notable deficiency of the standard .NET System.IO is the lack of support of advanced NTFS features, most notably extended-length path support (eg. file/directory paths longer than 260 characters).

Feature Highlights

  • Support for extended length paths (longer than 260 characters)
  • Creating Hardlinks
  • Accessing hidden volumes
  • Enumeration of volumes
  • Transactional file operations
  • Support for NTFS Alternate Data Streams
  • Accessing network resources (SMB/DFS)
  • ...and much more!

See: https://github.com/alphaleonis/AlphaFS

Use Robocopy as a workaround

There is an Article at the PowerShell Magazine that shows how to use Robocopy as a workaround

Parse Robocopy output in PowerShell to find long path names – Workaround for 260 character limit in Windows

http://www.powershellmagazine.com/2012/07/24/jaap-brassers-favorite-powershell-tips-and-tricks/

In the following example, we use Robocopy in the virtual mode with the option /l ($env:Temp is never used) .

The Option /l Specifies that files are to be listed only (and not copied, deleted, or time-stamped).

So all work is done only in Computer memory and not in the File system. This is really fast!

This example is to calculate the size of a folder incl. all subfolders. This works even with long pathes!

The Text output of Robocopy is examined and splited so that PowerShell gets only the amount of bytes.

Text processing is error-prone! You can even use the Robocopy Clone mentioned below!

1.$Ordner = 'c:\program files'
2.(robocopy.exe $Ordner $env:Temp /zb /e /l /r:1 /w:1 /nfl /ndl /nc /fp /bytes /np /njh) | Where-Object {$_ -like "*Bytes*"} | ForEach-Object { (-split $_)[1] }

See: http://social.technet.microsoft.com/Forums/en-US/ITCG/thread/30efc904-0aea-454e-a8d0-60408258126e/

Use a Share or a substitution as a workaround

You can access a Long Path even if you create a Share on a deep point of the Path.

Then you can use the Share to access files which are deeper than that point.

For example, if you create a Share or a drive substitution with "Subst" on a Folder, with the depth of 250 characters than you can access the rest of the Path by use of the Share. (But even that may fail)

PowerShell Path too Long and .NET

The MVP Joel 'Jaykul' Bennett picked up the work of the BCL Team and developed a PowerShell Module with a minimalistic set of PowerShell Cmdlets to deal with Long Paths.

See: http://huddledmasses.org/long-path-module-experimental-io/

PowerShell Robocopy Clone .NET

The MCT Ingo Karstein even picked up the work of the BCL Team and developed a full-blown Open source .NET PowerShell Robocopy Clone:

And here on Codeplex

This .NET Robocopy Clone supports even Path length up to 32,000 characters, but it is not very fast.

See Also