tags:

views:

377

answers:

5

Hi all,

I'm trying to delete a folder and the delete is failing due to the folder containing long paths. I presume I need to use something else instead of dir.Delete(true), Anyone crossed this bridge before?

Many thanks

 try
{
 var dir = new DirectoryInfo(@FolderPath);
 dir.Attributes = dir.Attributes & ~FileAttributes.ReadOnly;
 dir.Delete(true);
}
catch (IOException ex)
{
 MessageBox.Show(ex.Message);
}

This is the path in question: \server\share\dave\Private\Careers\Careers Ed\Fun Careers Education\Chris's not used 2006 to07\old 4.Careers Area Activity Week 1 30.10.06 or 6.11.06 or 13.11.06 Introduction to job levels and careers resources\Occupational Areas & Job levels Tutor Help Sheet[1].doc

+4  A: 

In the Windows API, the maximum length for a path is MAX_PATH, which is defined as 260 characters. A path is structured in the following order: drive letter, colon, backslash, components separated by backslashes, and a null-terminating character, for example, the maximum path on the D drive is D:\<256 chars>NUL.

The Unicode versions of several functions permit a maximum path length of approximately 32,000 characters composed of components up to 255 characters in length. To specify that kind of path, use the "\?\" prefix. The maximum path of 32,000 characters is approximate, because the "\?\" prefix can be expanded to a longer string, and the expansion applies to the total length.

For example, "\?\D:\". To specify such a UNC path, use the "\?\UNC\" prefix. For example, "\?\UNC\\". These prefixes are not used as part of the path itself. They indicate that the path should be passed to the system with minimal modification, which means that you cannot use forward slashes to represent path separators, or a period to represent the current directory. Also, you cannot use the "\?\" prefix with a relative path. Relative paths are limited to MAX_PATH characters.

The shell and the file system may have different requirements. It is possible to create a path with the API that the shell UI cannot handle.

c# (x) syntax (x)

 [DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool DeleteFile(string path);

For more information on the class, see http://msdn.microsoft.com/en-us/library/system

excerpt from:

http://www.codinghorror.com/blog/archives/000729.html

http://msdn.microsoft.com/en-us/library/aa363915%28VS.85%29.aspx

James Campbell
Hi, I've just tried this and I get the same error "Could not find part of the path 'long path and file name'". Do you know of anything else I can try?Thanks
Jamie
This works I tried it, works with a a path 300 characters long for me.
James Campbell
+4  A: 

The 260-character limitation (I assume that's the one you're running into) is an issue in Windows, not in .NET, unfortunately, so working around it can be difficult.

You might be able to work around it by changing your working directory such that the relative path for the delete is less than 260 characters; I don't know if that will work or not.

i.e.:

var curDir = Directory.GetCurrentDirectory();
Environment.CurrentDirectory = @"C:\Part\Of\The\Really\Long\Path";
Directory.Delete("Relative\Path\To\Directory");
Environment.CurrentDirectory = curDir;
technophile
you are missing a @ in Directory.Delete("Relative\Path\To\Directory");
Simon
and this does not seem to work
Simon
A: 

You could try using p/invoke to grab the "short" path name using the GetShortPathName function from kernel32.dll:

http://www.pinvoke.net/default.aspx/kernel32.GetShortPathName

Steve Danner
+2  A: 

Check the Win32 API: http://msdn.microsoft.com/en-us/library/aa363915%28VS.85%29.aspx

There it states: "In the ANSI version of this function, the name is limited to MAX_PATH characters. To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\?\" to the path."

Add the pinvoke:

using System;  
using System.Runtime.InteropServices;  
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]  
[return: MarshalAs(UnmanagedType.Bool)]  
internal static extern bool DeleteFile(string lpFileName);

Use it:

public static void DeleteLong(string fileName) {

    string LongName = @"\\?\" + fileName;
    DeleteFile(formattedName);
}
sparks
A: 

best I have so far is this

public static class IOHelper
{
    public static void DeleteDirectory(DirectoryInfo directoryInfo)
    {
        var emptyTempDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), "IOHelperEmptyDirectory"));
        emptyTempDirectory.Create();
        var arguments = string.Format("\"{0}\" \"{1}\" /MIR", emptyTempDirectory.FullName, directoryInfo.FullName);
        using (var process = Process.Start(new ProcessStartInfo("robocopy")
                                            {
                                                Arguments = arguments,
                                                CreateNoWindow = true,
                                                UseShellExecute = false,
                                            }))
        {
            process.WaitForExit();
        }
        directoryInfo.Delete();
    }
}
Simon