如何在.NET Framework C#项目中解决路径260字符长度限制问题
.NET Framework下解除Windows路径260字符限制的完整解决方案
系统层面配置生效要求
你修改注册表、组策略后未生效,先确认以下前置条件:
- 仅Windows 10 1607版本以上、Windows Server 2016版本以上系统原生支持长路径,低于该版本只能用
\\?\前缀方案 - 注册表修改路径为
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem下的LongPathsEnabled(DWORD类型)设为1,修改后必须重启系统才会生效 - 组策略修改路径为「计算机配置>管理模板>系统>文件系统>启用Win32长路径」,设为已启用后同样需要重启系统
.NET Framework项目额外配置
这是大部分用户修改系统配置后仍然报错的核心原因:
- 首先确认项目目标框架为.NET Framework 4.6.2及以上版本,低于该版本不支持原生长路径
- 打开项目的
app.config配置文件,在<configuration>节点下添加以下配置:
<runtime> <AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=false;Switch.System.IO.BlockLongPaths=false" /> </runtime>
完成该配置后,C#原生的Directory、FileInfo等IO类无需添加\\?\前缀,即可直接识别超过260字符的路径。
你现有代码的问题修复
\\?\前缀无效的原因
\\?\前缀有严格的格式要求:本地路径格式为\\?\C:\xxx\yyy,UNC网络路径格式为\\?\UNC\server\share\path,你直接拼接@"\\?\" + subdir.FullName如果是UNC路径会出现格式错误,导致系统无法识别。
批处理参数传递错误
你当前的参数拼接逻辑把bat文件自身路径作为第一个参数传递了,导致批处理拿到的%1不是你想要的源路径,修正写法如下:
// 路径前后加双引号,避免路径包含空格时报错 proc.StartInfo.Arguments = String.Format("\"{0}\" \"{1}\"", sousdoss, temppath);
更稳定的实现方案(无需调用xcopy批处理)
配置好.NET长路径开关后,直接用C#原生IO类递归拷贝即可,比调用外部批处理更可控,修改后的参考代码如下:
private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs) { DirectoryInfo dir = new DirectoryInfo(sourceDirName); if (!dir.Exists) { throw new DirectoryNotFoundException( "源目录不存在或无法访问:" + sourceDirName); } // 目标目录不存在则创建 if (!Directory.Exists(destDirName)) { Directory.CreateDirectory(destDirName); } // 拷贝当前目录下的所有文件 foreach (FileInfo file in dir.GetFiles()) { string temppath = Path.Combine(destDirName, file.Name); try { file.CopyTo(temppath, false); } catch (Exception ex) { Erreurs.Add(ex.Message); Erreurs.Add(temppath); } } // 递归拷贝子目录 if (copySubDirs) { foreach (DirectoryInfo subdir in dir.GetDirectories()) { string temppath = Path.Combine(destDirName, subdir.Name); try { DirectoryCopy(subdir.FullName, temppath, copySubDirs); } catch(Exception ex) { Erreurs.Add(ex.Message); Erreurs.Add(temppath); } } } }
如果你的项目无法升级到.NET Framework 4.6.2+,可以安装NuGet包Microsoft.IO.Redist,替换原生的System.IO类使用即可支持长路径。
内容的提问来源于stack exchange,提问作者Benjamin DE MELO
相关产品推荐
相关产品推荐

