Interesting Exceptions: C# - PathTooLongException

January 27, 2011 by C#  

When I told one of my developer friends that I am going to write a post about the PathTooLongException, he found it rather amusing - how much could there really be to this Exception?

In Windows the full path of a file/folder can't be longer than 260 characters, this limit is enforced by the .net framework and normally by the operating system as well (one can't create a full path longer than 260 characters via windows explorer for example).

But recently however, I noticed a more interesting issue surrounding this exception while importing folders/files using a tool I wrote - quite a number of the paths exceeded the 260 character limit and obviously raised the PathTooLongException when the code attempted to import the folders/files.

Which obviously means that this limit can't exactly be set in stone.

After doing some digging (and playing around), I found its possible to circumvent the 260 limit programatically (Win32 API - Unicode via the "\\?\" prefix) and using 8.3 path names via the Windows console as well (upto aprox 32000 characters).

In the following snippet we succeed in creating paths longer than 260 characters via 8.3 file/folder names:

c:
cd\
md aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
cd aaaaaa~1
md aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
cd aaaaaa~1
dir c:\ > test.txt

The interesting thing (after running this snippet) on Windows XP/2003, is that one can't even browse to the file within the second folder - but on Windows 7/2008 (and I would imagine Vista as well) it was possible to browse to that file at least.

Now if we try to delete the folder (created via the previous snippet) using windows explorer, windows will swear at us (whoops you've just created a folder you can't remove, bwahaha).

Just joking, you will be able to remove those folders using the following snippet:

c:
cd\aaaaaa~1\aaaaaa~1
del test.txt
cd..
rd aaaaaa~1
cd..
rd aaaaaa~1

As for the second way (that I know of) to sidestep the 260 character limit, can be seen in the following extremely crude snippet (don't use as is) - via the Win32 API.

using System;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;

public static class LongPath
{
    static class Win32Native
    {
        [StructLayout(LayoutKind.Sequential)]
        public class SECURITY_ATTRIBUTES
        {
            public int nLength;
            public IntPtr pSecurityDescriptor;
            public int bInheritHandle;
        }

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool CreateDirectory(string lpPathName, SECURITY_ATTRIBUTES lpSecurityAttributes);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, FileShare dwShareMode, SECURITY_ATTRIBUTES securityAttrs, FileMode dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);
    }

    public static bool CreateDirectory(string path)
    {
        return Win32Native.CreateDirectory(String.Concat(@"\\?\", path), null);
    }

    public static FileStream Open(string path, FileMode mode, FileAccess access)
    {
        SafeFileHandle handle = Win32Native.CreateFile(String.Concat(@"\\?\", path), (int)0x10000000, FileShare.None, null, mode, (int)0x00000080, IntPtr.Zero);
        if (handle.IsInvalid)
        {
            throw new System.ComponentModel.Win32Exception();
        }
        return new FileStream(handle, access);
    }
}

The interesting thing to note here, is that each segment created like this can't be longer than 255 characters (which is a bit longer than the folder names we can create via the 8.3 method) e.g. "c:\<255>\<255>\<255.ext>".

In the next snippet we apply the LongPath class as seen in the preceding snippet, which demonstrates how to access these files programmatically.

string path = @"c:\".PadRight(255, 'a');
LongPath.CreateDirectory(path);

path = String.Concat(path, @"\", "".PadRight(255, 'a'));
LongPath.CreateDirectory(path);

string filename = Path.Combine(path, "test.txt");
        
FileStream fs = LongPath.Open(filename, FileMode.CreateNew, FileAccess.Write);

using (StreamWriter sw = new StreamWriter(fs))
{
    sw.WriteLine("abc");
}

Another interesting thing to note, is that one can't browse to the folders created in the preceding snippet, in any of the Windows Operating systems - it is however still possible to access them via the windows console using 8.3 file/folder names.

All of this is a bit of an ugly situation, infact most of the apps I tested didn't support reading/importing files affected by this issue. Is this an issue we must simply ignore?

Additional Reading
http://www.hanno.co.za/post/2011/04/04/Copying-files-with-very-long-filenames-paths.aspx http://msdn.microsoft.com/en-us/library/aa365247.aspx
http://blogs.msdn.com/b/bclteam/archive/2007/02/13/long-paths-in-net-part-1-of-3-kim-hamilton.aspx
http://vlaurie.com/computers2/Articles/filenames.htm


Leave a Comment


mr August 12, 2024 by Mark Carlson

Yeah it can be a real headache, I tried LongPath Tool Program which helped a lot.

Missing the point October 2, 2016 by Christoff Truter

Like mentioned in March, the goal of this post is to solve the problem from a programming perspective.

Long path tool October 2, 2016 by stepan raisa

Long path error! "Long path tool" is very helpful for this problem. You can solve this problem like copy, delete, long path files by using this tool. I used to have similar problems too, but after using "long path tool" everything was solved. Try this software and you would be glad you did.

March 23, 2016 by Christoff Truter

@francesca that kinda misses the point of what a programming site is all about, the aim is to show people how to write a tool like that, you're also not going to use a tool like that if you've got an application using functionality like this inside an application you wrote ;)

March 23, 2016 by francesca

Try Long Path Tool. It Works.

Re: More information March 19, 2012 by Christoff Truter

Hmmm, will you be able to give me more information? Like the exact string for example that you're using to access the path?

cannot get your code to work March 18, 2012 by Anonymous

Thanks for the informative article. I have a file path which is 261 long. I cannot get your code to run. It returns handle.IsInvalid==true.