问题:
把一个超长路径传入了File对象 或者 Directory的某个方法,例如:
(或者一些三方类库,类似于这样传入了一些超长路径)
string path = "c://超长路径/超长路径/......./超长路径";
File.Create(path);
File.Delete(path);
Directory.Exists(path);
Directory.GetFiles(path);
ZipFile.CreateFromDirectory(文件夹目录, 超长的zip路径);//压缩文件夹
ZipFile.ExtractToDirectory(zip路径,超长的输出目录);//解压缩文件夹
会报异常
未找到路径XXX的一部分
解决方法一:
在路径盘符前增加\\?\,例如:
string path = @"\\?\"+"c://超长路径/超长路径/......./超长路径";
File.Create(path);
*目测只适用于windows提供的类库,File、Directory等,其他三方库不一定支持这样的写法。
解决方法二:
总体思路是借助cmd命令代替SDK调用的写法,把超长路径传入cmd命令行中执行。
cmd是不支持\\?\写法的路径的
例如可以用如下代码替代FIle.Delete(path)
完整工具类附后
string cmd = "del /f /q \"" + fullPath + "\"";// /Q 是静默执行
RunCmd(cmd, out string output);
如果是解压缩之类操作,也可以用cmd调用7z等压缩工具代替SDK的写法
7z工具包去官网下载https://7-zip.org/
安装后把7z.dll 和 7z.exe 放进debug目录使用最方便
有个7za.exe工具包,不支持解压rar
//使用7z.exe解压
//-q:执行时不显示任何信息;
//-y:不必先询问用户,unzip执行后覆盖原有的文件;
//-o<目录>:指定文件解压缩后所要存储的目录;
//更多参数,参考https://www.cnblogs.com/wzmm/articles/16488599.html
Process process = Process.Start(
new ProcessStartInfo{
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow=true,
RedirectStandardOutput =true,
UseShellExecute= false,
FileName = AppDomain.CurrentDomain.BaseDirectory + "/7z.exe",
//-o后无空格,两个路径前后有引号,避免路径中有空格、特殊符号问题
Arguments = " x \"" + zippath + "\" -y -o\"" + target_path + "\""
}
);
process.WaitForExit();
string message = process.StandardOutput.ReadToEnd();//要等压缩完成后才可以来抓取这个压缩文件
if (message.IndexOf("Ok") == -1)
{
throw new Exception(message);
}
比较全的cmd操作文件的工具类
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace sunzip
{
internal class CmdHelper
{
/// <summary>
/// 命令行删除文件
/// </summary>
/// <param name="fullPath"></param>
public static void CmdDelFile(string fullPath)
{
try
{
string cmd = "del /f /q \"" + fullPath + "\"";// /Q 是静默执行
RunCmd(cmd, out string output);
}
catch (Exception ex)
{
}
}
/// <summary>
/// 命令行删除文件夹及子文件
/// </summary>
/// <param name="fullPath"></param>
public static void CmdDelDir(string fullPath)
{
try
{
string cmd = "rmdir /s/q \"" + fullPath + "\"";// /S 删除文件夹及文件夹下的子文件和文件夹
RunCmd(cmd, out string output);
Console.WriteLine( "xxxxxxxxxxxxxxxxx"+output);
}
catch (Exception ex)
{
}
}
/// <summary>
/// 执行Cmd命令
/// </summary>
public static void RunCmd(string cmd, out string output)
{
cmd = cmd.Trim().TrimEnd('&') + "&exit";//不管命令是否成功,均质性exit
using (Process p = new Process())
{
string cmdPath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "cmd.exe");
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/c " + cmdPath;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.Verb = "RunAs";
p.Start();
p.StandardInput.WriteLine(cmd);
p.StandardInput.AutoFlush = true;
output = p.StandardOutput.ReadToEnd();
p.WaitForExit();//等待程序执行完,退出进程
p.Close();
}
}
}
}