PathTooLongException C# 4.5
Asked Answered
J

3

5

I having trouble of copying some folder 260+ chars (for example: F:\NNNNNNNNNNNNNNNN\NNNNNNNNNNN\ROOT\$RECYCLE.BIN\S-1-5-21-3299053755-4209892151-505108915-1000\$RMSL3U8\NNNNNNNNN NNNNNNNN\NNNNNNNNNNN\NNNNNNNNNN\NNNNNNNNNN\publish\Application Files\TNNNNNNNNNNNN_1_0_0_0\NNNNNNNNNNNN.exe.manifest) to some other place with standart DrectoryInfo.Create(); adding \?\ or \?\UNC\ (like "\\?\UNC\") just throw another ArgumentException. What am i doing wrong? What else i can do without using Directory.SetCurrentDirectory() ?

Jessamyn answered 5/10, 2012 at 13:19 Comment(1)
Possible duplicate of How to avoid System.IO.PathTooLongException?Divergency
A
5

Yes, using the standard APIs will give you this kind of limitations (255 chars IIRC).

From .NET you can use the AlphaFS project which lets you use very long paths (using the "\\?\" style) and mimics the System.IO namespace.

You will probably be able to use this library just as if you were using System.IO, for example : AlphaFS.Win32.Filesystem.File.Copy() instead System.IO.File.Copy()

If you don't want or cannot use AlphaFS you'll have to pinvoke the Win32 API

Assiduous answered 5/10, 2012 at 13:23 Comment(6)
english and experience problem. What is "have to ****pinvoke the Win32**** API"?Kally
I meant "call native Windows API C/c++ functions" using something called p/invoke in .Net language.Assiduous
If you lack experience for the moment I recommend you try AlphaFS, it will be much easier.Assiduous
Well, now it's the most nicely and easiest answer about that problem on Stackoverflow, well done! :DKally
Thanks! And if you don't want AlphaFS and prefer "p/invoking", take a look at the great answer from Vinoth below.Assiduous
Do NOT download the "recommended" AlphaFS release. Lots of bugs in it. The latest source code is your best bet.Sogdiana
R
8

Actually you need to call win32 from c#. We have done this

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);
    }
}

A sample code:

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");
}
Ritzy answered 5/10, 2012 at 13:31 Comment(0)
C
8

There's a great library on Microsoft TechNet for overcoming the long filenames problem, it's called Delimon.Win32.I​O Library (V4.0) and it has its own versions of key methods from System.IO

For example, you would replace:

System.IO.Directory.GetFiles

with

Delimon.Win32.IO.Directory.GetFiles

which will let you handle long files and folders.

From the website:

Delimon.Win32.IO replaces basic file functions of System.IO and supports File & Folder names up to up to 32,767 Characters.

This Library is written on .NET Framework 4.0 and can be used either on x86 & x64 systems. The File & Folder limitations of the standard System.IO namespace can work with files that have 260 characters in a filename and 240 characters in a folder name (MAX_PATH is usually configured as 260 characters). Typically you run into the System.IO.PathTooLongException Error with the Standard .NET Library.

Caughey answered 16/2, 2013 at 6:1 Comment(1)
Delimon is great, I have used it for a while now, but it doesn't support FileStream. As Vinoth said, its best to call Win32 from C#.Scribe
A
5

Yes, using the standard APIs will give you this kind of limitations (255 chars IIRC).

From .NET you can use the AlphaFS project which lets you use very long paths (using the "\\?\" style) and mimics the System.IO namespace.

You will probably be able to use this library just as if you were using System.IO, for example : AlphaFS.Win32.Filesystem.File.Copy() instead System.IO.File.Copy()

If you don't want or cannot use AlphaFS you'll have to pinvoke the Win32 API

Assiduous answered 5/10, 2012 at 13:23 Comment(6)
english and experience problem. What is "have to ****pinvoke the Win32**** API"?Kally
I meant "call native Windows API C/c++ functions" using something called p/invoke in .Net language.Assiduous
If you lack experience for the moment I recommend you try AlphaFS, it will be much easier.Assiduous
Well, now it's the most nicely and easiest answer about that problem on Stackoverflow, well done! :DKally
Thanks! And if you don't want AlphaFS and prefer "p/invoking", take a look at the great answer from Vinoth below.Assiduous
Do NOT download the "recommended" AlphaFS release. Lots of bugs in it. The latest source code is your best bet.Sogdiana

© 2022 - 2024 — McMap. All rights reserved.