C#删除具有长路径的文件夹

时间:2010-02-08 16:19:31

标签: c# directory

我正在尝试删除文件夹,并且由于包含长路径的文件夹,删除失败。我认为我需要使用其他东西而不是dir.Delete(true),任何人之前都穿过这座桥?

非常感谢

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

这是有问题的路径: \ 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工作水平和职业资源简介\职业领域&工作级别Tutor帮助表[1] .doc

9 个答案:

答案 0 :(得分:10)

  

在Windows API中,路径的最大长度为MAX_PATH,定义为260个字符。本地路径按以下顺序构成:驱动器号,冒号,反斜杠,由反斜杠分隔的名称组件以及终止空字符。例如,驱动器D上的最大路径是“D:\某个256个字符的路径字符串<NUL>”,其中“<NUL>”表示当前系统代码页的不可见的终止空字符。 (字符&lt;&gt;在此处用于视觉清晰度,不能是有效路径字符串的一部分。) [MSDN]

多个函数的Unicode版本允许最大路径长度约为32,000个字符,由长度最多255个字符的组件组成。要指定该类型的路径,请使用"\\?\"前缀。 32,000个字符的最大路径是近似值,因为"\\?\"前缀可以扩展为更长的字符串,并且扩展适用于总长度。

例如,"\\?\D:\<path>"。要指定此类UNC路径,请使用"\\?\UNC\"前缀。例如,"\\?\UNC\<server>\<share>"。这些前缀不会用作路径本身的一部分。它们表明路径应该以最小的修改传递给系统,这意味着您不能使用正斜杠来表示路径分隔符,也不能使用句点来表示当前目录。此外,您不能将"\\?\"前缀与相对路径一起使用。相对路径限制为MAX_PATH字符。

shell和文件系统可能有不同的要求。可以使用shell UI无法处理的API创建路径。

C#语法:

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

有关课程的更多信息,请参阅System Namespace - MSDN

摘自:

Filesystem Paths: How Long is Too Long? - Coding Horror

DeleteFile function (Windows) - MSDN

答案 1 :(得分:4)

到目前为止我最好的是

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

答案 2 :(得分:3)

260个字符的限制(我假设你正在遇到的那个)是Windows中的一个问题,不幸的是在.NET中,因此解决它可能很困难。

可能可以通过更改工作目录来解决此问题,以便删除的相对路径少于260个字符;我不知道这是否有效。

即:

var curDir = Directory.GetCurrentDirectory();
Environment.CurrentDirectory = @"C:\Part\Of\The\Really\Long\Path";
Directory.Delete("Relative\Path\To\Directory");
Environment.CurrentDirectory = curDir;

答案 3 :(得分:3)

我不知道这个问题是否仍然存在,但我解决了这个问题。代码是在win7机器上开发的,带有VS2008。这些是我为解决问题而采取的步骤

  1. 创建一个空的VS C#项目
  2. 添加对此COM对象的引用: microsoft scripting runtime
  3. 添加使用脚本;到你的使用清单
  4. 在代码中的某处,创建一个类似于此的函数:

    private static void DeletePathWithLongFileNames(string path)
    {
        var tmpPath = @"\\?\"+ path
        FileSystemObject fso = new FileSystemObjectClass() as FileSystemObject;
        fso.DeleteFolder(tmpPath, true); 
    }
    
  5. 路径参数是您要删除的目录。该函数预先设置unicode路径签名,创建FileSystemObject实例并删除 unicode 路径及其所有内容。

    • 编译程序,使用管理权限启动生成的.exe文件(在win7上以管理员身份运行),找出要删除的目录并在其上应用此功能。然后,观看长文件名。

    毋庸置疑,它很强大......而且很危险。伟大的力量带来了巨大的责任:-)

答案 4 :(得分:2)

这是我用来删除经常出现长路径的主目录:

public static void DirectoryDeleteLong(string directoryPath)
{
    var emptyDirectory = new DirectoryInfo(Path.GetTempPath() + "\\TempEmptyDirectory-" + Guid.NewGuid());
    try
    {
        emptyDirectory.Create();
        using (var process = new Process())
        {
            process.StartInfo.FileName = "robocopy.exe";
            process.StartInfo.Arguments = "\"" + emptyDirectory.FullName + "\" \"" + directoryPath + "\" /mir /r:1 /w:1 /np /xj /sl";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = true;
            process.Start();
            process.WaitForExit();
        }
        emptyDirectory.Delete();
        new DirectoryInfo(directoryPath).Attributes = FileAttributes.Normal;
        Directory.Delete(directoryPath);
    }
    catch(IOException) { }
}

它类似于Simon发布的解决方案,但也是:

  • 降低robocopy的高默认重试次数。
  • 重置属性,因为对于标记为只读的任何内容,directory.delete将失败。
  • 创建一个唯一的空目录名,以便它适用于多个线程。

答案 5 :(得分:1)

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

它声明:“在此函数的ANSI版本中,名称仅限于MAX_PATH字符。要将此限制扩展为32,767个宽字符,请调用函数的Unicode版本并在路径前加上”\?\“ “。

添加pinvoke:

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

使用它:

public static void DeleteLong(string fileName) {

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

答案 6 :(得分:0)

您可以尝试使用p / invoke使用kernel32.dll中的GetShortPathName函数获取“短路径”名称:

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

答案 7 :(得分:0)

以下链接显示了System.IO中长路径支持的.NET内部实现,它不是通过Reflector生成的最简单的,但包含许多使用前面提到的Win32 API的示例。

http://reflector.webtropy.com/default.aspx/4@0/4@0/untmp/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/clr/src/BCL/System/IO/LongPath@cs/1305376/LongPath@cs

如果通过System.IO提供此功能会很好,因为支持显然在那里!

答案 8 :(得分:0)

我创建了一个Managed .Net库来处理文件和文件夹。

https://github.com/DotNetIO

var fs = LocalFileSystem.Instance : FileSystem

^^^^在IoC中的地方

fs.GetDirectory(@"C:\\a very very long path ...\with\subdirs\and files.txt").Delete();

干杯