January 27, 2011 by Christoff Truter 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
c: cd\aaaaaa~1\aaaaaa~1 del test.txt cd.. rd aaaaaa~1 cd.. rd aaaaaa~1
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); } }
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"); }
mr August 12, 2024 by Mark Carlson
Yeah it can be a real headache, I tried LongPath Tool Program which helped a lot.