InnoSetup安装时tmp目录路径过长报错,求非缩短路径的通用解法
InnoSetup长路径文件复制失败的解决方案(除缩短路径外)
问题背景
我制作的安装程序包含从网站爬取的文档,生成的目录结构非常复杂,导致部分路径及文件名长度超过260字符,使得InnoSetup从{tmp}目录复制文件时报错找不到文件。我已经在[Files]段为Source和DestDir参数使用UNC路径来避免构建和安装阶段的问题,但从{tmp}的解压目录复制时仍然失败。过长路径示例如下:
C:\Users\XXXXXX\AppData\Local\Temp\is-H7H6B.tmp\7de477cab9790185e1d8d84a307e35588102956b2cc825c1cd9a4b289cfd2505\Samples\Learn\OfflineHelp\https.docs.XXXXXXXXXXXXX\images\thumb\3\38\Setup_XXXXXXXXXXXXXXXXX_parameters.png\460px-Setup_XXXXXXXXXXXXXXXXX_parameters.png
注:我的Windows系统已启用长路径支持。
通用解决方案
启用InnoSetup内置长路径支持
InnoSetup 6.0及以上版本提供了LongPathSupport指令,在[Setup]段添加以下配置,可让安装程序自动适配长路径(包括{tmp}目录下的操作):
[Setup] LongPathSupport=yes
该功能要求Windows 10 1607及以上版本,与你已启用系统长路径支持的环境兼容。
映射临时目录为驱动器号
通过[Code]段创建自定义临时目录,并用subst命令映射为短驱动器号,绕过长路径限制:
[Code] var TempDrive: String; ResultCode: Integer; procedure InitializeSetup; var TempPath: String; begin // 创建自定义临时目录 TempPath := ExpandConstant('{tmp}\ShortTmp'); ForceDirectories(TempPath); // 分配未使用的驱动器号(可根据实际调整) TempDrive := 'Z:'; // 执行映射命令 if not Exec('subst.exe', TempDrive + ' "' + TempPath + '"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then MsgBox('临时驱动器映射失败', mbError, MB_OK); end; procedure DeinitializeSetup; begin // 卸载驱动器映射 Exec('subst.exe', TempDrive + ' /d', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); end;
后续在[Files]段或自定义复制逻辑中,使用映射的驱动器路径替代原长路径即可。
调用Windows API手动复制文件
在[Code]段调用CopyFileW API,手动处理长路径文件复制,路径需添加\\?\前缀:
[Code] function CopyFileW(lpExistingFileName, lpNewFileName: WideString; bFailIfExists: Boolean): Boolean; external 'CopyFileW@kernel32.dll stdcall'; procedure CopyLongPathFile(SourcePath, DestPath: String); var LongSource, LongDest: WideString; begin // 转换为长路径格式 LongSource := '\\?\' + SourcePath; LongDest := '\\?\' + DestPath; if not CopyFileW(LongSource, LongDest, False) then MsgBox('文件复制失败: ' + SysErrorMessage(GetLastError()), mbError, MB_OK); end;
可在CurStepChanged等事件中,调用该函数完成从{tmp}到目标目录的复制操作。
缩短InnoSetup临时目录路径
InnoSetup默认的临时目录会生成随机长名字子目录,可通过[Setup]段自定义临时目录路径,减少基础路径长度:
[Setup] TempDir={tmp}\ST
这样能为后续的文档路径预留更多字符空间,避免总长度超限。
内容的提问来源于stack exchange,提问作者Markus Heckmann
相关产品推荐
相关产品推荐

