如何执行路径超300字符的BAT文件?解决CreateProcess报错问题
解决CreateProcess调用长路径BAT文件的“文件名或扩展名过长”问题
问题根源
直接给CreateProcess传递带\\?\前缀的BAT路径无效,是因为系统实际会调用cmd.exe执行BAT,但cmd.exe默认不识别\\?\格式的长路径,导致解析失败。
解决方案1:正确构造CreateProcess的调用参数
将cmd.exe作为目标应用程序,在命令行参数中用双层引号包裹带\\?\前缀的BAT路径,确保cmd.exe能正确解析长路径:
var BatPath: string; CmdLine: string; CmdLineBuf: array[0..4095] of Char; StartupInfo: TStartupInfo; ProcessInfo: TProcessInformation; begin BatPath := '\\?\C:\你的超长路径\目标脚本.bat'; // 构造cmd命令行,双层引号确保长路径被正确识别 CmdLine := Format('/c ""%s""', [BatPath]); StrPCopy(CmdLineBuf, CmdLine); FillChar(StartupInfo, SizeOf(StartupInfo), 0); StartupInfo.cb := SizeOf(StartupInfo); if CreateProcess(nil, CmdLineBuf, nil, nil, False, 0, nil, nil, StartupInfo, ProcessInfo) then begin // 可选:等待进程执行完毕 WaitForSingleObject(ProcessInfo.hProcess, INFINITE); CloseHandle(ProcessInfo.hProcess); CloseHandle(ProcessInfo.hThread); end; end;
注意:CreateProcess的lpCommandLine参数需要可写内存,所以用数组缓冲区存储命令行字符串,避免直接传常量字符串。
解决方案2:改用ShellExecuteEx(更简便)
ShellExecuteEx对长路径的支持更友好,无需手动处理cmd.exe的调用逻辑,直接传入带\\?\前缀的BAT路径即可:
var ShellInfo: TShellExecuteInfo; begin FillChar(ShellInfo, SizeOf(ShellInfo), 0); ShellInfo.cbSize := SizeOf(ShellInfo); ShellInfo.fMask := SEE_MASK_NOCLOSEPROCESS; // 直接传入带\\?\前缀的长路径 ShellInfo.lpFile := PChar('\\?\C:\你的超长路径\目标脚本.bat'); ShellInfo.nShow := SW_SHOWNORMAL; if ShellExecuteEx(@ShellInfo) then begin // 可选:等待进程执行完毕 WaitForSingleObject(ShellInfo.hProcess, INFINITE); CloseHandle(ShellInfo.hProcess); end; end;
内容的提问来源于stack exchange,提问作者Seekr
相关产品推荐
相关产品推荐

