S h o r t S t o r i e s

// Tales from software development

Using long paths in .NET

with one comment

Long paths

One of the limitations of the .NET Framework is that the Directory, DirectoryInfo, File, FileInfo, and Path classes in the System.IO namespace are limited to a maximum path length of MAX_PATH (defined as 260) characters. This used to be a limitation imposed by MS-DOS and Windows but the Windows API now supports paths of up to 32,000 characters.

So why does the .NET Framework continue to have this restriction ? Sadly, it’s just down to effort, or rather the lack of time to implement long path support in the framework. This is discussed in the .NET Framework team’s blog in Long Paths in .NET, Part 1 of 3.

What the \\?\ ?

Long paths are supported in the Unicode versions of some of the Windows API functions using a special syntax. Prepending the character sequence \\?\ to a path passed into a function indicates that it’s a long path.

UNC paths are handled slightly differently and use this syntax: \\?\UNC\<machine-name>\<share-name>. So, for example, the UNC path \\Neptune\Files becomes \\?\UNC\Neptune\Files.

Note that each directory component of a long path cannot exceed 255 characters in length. You also need to be aware that using the long path format turns off some of the massaging that the API functions perform, e.g. resolving references to ‘.’ and ‘..’, and converting relative paths to full paths.

There’s no indication that long paths will be supported by the .NET Framework in the near future so if you need to use them you’ll have to use P/Invoke to call the Windows API functions directly.

Most of the time you’re unlikely to need long path support as Windows doesn’t generally support it. For example, Windows Explorer does not support long paths. However, you might run into situations where you do need it. I recently wrote a small application to backup files on a network attached storage (NAS) device. This device runs a UNIX based OS and uses SAMBA to provide network file storage. Some of the paths that my application needed to process exceeded MAX_PATH length and the .NET Framework classes that I was using (System.IO’s Directory and File classes) threw exceptions.

My solution was to implement slimmed down versions of File, FileInfo, Directory, and DirectoryInfo. These classes mapped the paths passed to their methods to long path formatted strings (i.e. prepended with \\?\ and \\?\UNC\ as appropriate) that were used internally when calling the Unicode versions of the various Windows API functions required. The paths returned by methods such as Directory.GetDirectories() and Directory.GetFiles() are normal paths (i.e. without the \\?\ prefix) which may, technically, be invalid as they may be longer than MAX_PATH. However, as long as these paths are only ever passed to my classes rather than the System.IO classes, the paths are handled correctly.

The classes and methods that you’re likely to need to implement, as a minimum, are:

  • Directory
    • Exists(path)
    • GetDirectories(path)
    • GetFiles(path)
  • File
    • Copy(sourceFileName, destFileName)
    • Exists(path)
    • CreationTime(path)
    • LastAccessTime(path)
    • LastWriteTime(path)

For the most part it’s quite easy to implement these classes and methods using the Windows API functions but you need to be aware of some differences in the behaviour of API functions and their equivalent System.IO methods. For example, the .NET Framework Directory.CreateDirectory() will create all the required directories in a path whereas the CreateDirectory Windows API function will only create a single directory within an existing path. It’s not difficult to implement the .NET Framework behaviour but you need to be aware of where the differences lie.

Summary

  • The .NET Framework does not support paths longer than MAX_PATH (260) characters
  • Use the Unicode versions of Windows API functions such as FileFindFirst, FileFindNext, FindClose, CreateDirectory, etc.
  • Use \\?\ and \\?\UNC\ prefixes to enable long path support in these Windows API functions.

References

Long Paths in .NET, Part 1 of 3 – The .NET Framework team blog entry about long paths.

Naming a file – MSDN page describing file and path names and the use of the \\?\ prefix.

PInvoke wiki – A wiki of PInvoke signatures for .NET languages.

Advertisements

Written by Sea Monkey

April 6, 2008 at 9:35 pm

Posted in Development

Tagged with ,

One Response

Subscribe to comments with RSS.

  1. Love the way you have summarized.. Too good

    Somya

    February 18, 2016 at 3:56 pm


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: