Inno Setup Compiler "Cannot find the path specified" 长路径错误

Inno Setup Compiler "Cannot find the path specified" error with long paths

我正在使用 .iss 脚本在 Inno Setup Compiler 中构建一个 exe 文件。我需要将一些 node_modules 打包到这个应用程序中,所以我在 [Files] 下有一行看起来像这样:

Source: "{#SourcePath}Encore.Warehouse.UI\bin\Warehouse_Release\warehouse\*"; \
    DestDir: "{app}\warehouse"; Flags: ignoreversion recursesubdirs createallsubdirs

当我编译时,我收到这个错误:

编译器输出如下:

因此,它 看起来 运行 很好,直到它中止。我最初的想法是 browser.js 不存在,但经过仔细检查后,情况并非如此。此外,我在源路径中使用了通配符,因此 编译器知道该文件存在 ,但它似乎无法压缩它。

可能导致问题的另一件事是文件路径长度。由于嵌套的依赖关系,节点模块通常最终具有 荒谬的文件路径长度 。在这种情况下,路径长度为 260。假设这是导致问题的原因,有什么办法可以解决这个问题吗?

肯定是路途遥远。通常 Windows 应用程序不能处理长度超过 MAX_PATH(260 个字符)的路径。
请参阅 Microsoft 文档中的 Naming Files, Paths, and Namespaces

一个常见的解决方法是在路径前加上 \?\ 前缀(再次参见上面的 Microsoft 文章)。前缀只能用于绝对路径。但是 Inno Setup 编译器用 Source 属性阻塞了它。它查找 : 并且它只接受仅在 : 之前具有驱动器号或使用 compiler:userdocs: 前缀的路径。

您可以通过使用带有卷 ID(因此没有冒号)的 UNC 路径来破解它。

使用 mountvol 命令查找源驱动器的 UNC 路径。

然后在安装时(不是在编译时),带有 DestDir 属性的长路径也会遇到同样的问题。那里,冒号没有问题,所以你可以简单地使用 \?\ 前缀。

Source: "\?\Volume{bb919c3e-bdb1-42b8-9601-6715becd8683}\{#SourcePath}Encore.Warehouse.UI\bin\Warehouse_Release\warehouse\*"; \
    DestDir: "\?\{app}\warehouse"; Flags: ignoreversion recursesubdirs createallsubdirs

当然,如果问题是根路径已经太长引起的,您只需将源文件移动到路径较短的文件夹即可解决问题。或者您可以使用 subst 创建一个虚拟驱动器,或者您可以创建一个 symlink/directory 结点。

遇到同样的问题,下面是关于 subst 解决方法的更多详细信息,如评论和接受的答案中所述。

下面是一些 precompile.bat 文件的内容,用于将一些本地路径与 A: 驱动器号相关联

@echo off
REM NB: Removing any previous association to be sure new one will work
subst A: /D 1> NUL 2>&1
subst A: "%~dp0.."

还有一些内容postcompile.bat最后解除关联

@echo off
subst A: /D 1> NUL 2>&1

NB1:小心,一旦关联,就很难在 .iss 脚本中直接导航上层路径,因为 A:\.. 仍然是 A:\ !(我陷入了这个问题,所以值得知道)。然后应直接在 precompile.bat.

中与所有必需文件的最近最顶层文件夹建立关联

NB2:不知道是否可以提醒之前的关联,最后恢复

可以将这些步骤添加到 .iss 脚本中,如下所示:

[PreCompile]
Name: "precompile.bat"; Flags: cmdprompt redirectoutput

[PostCompile]
Name: "postcompile.bat"; Flags: cmdprompt redirectoutput

最后请注意,[PreCompile][PostCompile] 部分将仅从 IDE 执行。它们不会从命令行执行(至少在 inno 5.5.9 中),我也属于这个......所以从命令行完成编译应该是这样的:

call "precompile.bat"
call "%ProgramFiles(x86)%\Inno Setup 5\ISCC.exe" "myscript.iss"
call "postcompile.bat"

注意:我认为调用 Compil32.exe /cc "myscript.iss"(IDE 编译器)而不是 ISCC.exe(命令行编译器)应该 运行 [PreCompile][PostCompile] 部分,但在我的例子中,我必须将额外的 /D 选项传递给编译器,因此无法直接调用 Compil32.exe