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

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

非常感谢

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 used 2006 to07 \ old 4.Careers Area Activity Week 1 30.10.06 or 6.11.06 or 13.11.06职业水平和职业资源简介\职业领域和职位级别教师帮助表[1] .doc

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

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

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

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

C#语法:

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

有关该类的详细信息,请参阅系统命名空间 – MSDN

摘录自:

文件系统路径:太长了多长时间? – 编码恐怖

DeleteFile函数(Windows) – MSDN

我到目前为止最好的是这个

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

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; 

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

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

     private static void DeletePathWithLongFileNames(string path) { var tmpPath = @"\\?\"+ path FileSystemObject fso = new FileSystemObjectClass() as FileSystemObject; fso.DeleteFolder(tmpPath, true); } 

Path参数是您要删除的目录。 该函数预先设置unicode路径签名,创建FileSystemObject实例并删除unicode路径及其所有内容。

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

不用说,它是强大的……而且很危险。 拥有权利的同时也被赋予了重大的责任 :-)

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

 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将失败。
  • 创建一个唯一的空目录名称,以便它可以与多个线程一起使用。

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

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

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

以下链接显示了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提供此function会很好,因为支持显然在那里!

我创建了一个托管的.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(); 

干杯