无法 运行 自解压安装程序 - 无法访问 jarfile C:\Users\Ray\AppData\Local\Temp\RarSFX0\install.jar

Unable to run self-extracting installer - Unable to access jarfile C:\Users\Ray\AppData\Local\Temp\RarSFX0\install.jar

我有一个 Java 应用程序,Izpack 安装程序用 launch4j64bit 打包,然后捆绑为自解压 ZIP,用 WinRAR[= 创建47=] 5.20 使用

上的答案中描述的方法

它对我和大多数客户都有效,但最近有一些客户报告了这样的错误:

Unable to access jarfile C:\Users\Ray\AppData\Local\Temp\RarSFX0\install.jar

我无法重现此错误。

是什么导致了这个问题?它与 Windows 更新有关吗?

只有自解压版本有问题,用户必须自己解压的常规 .zip 文件才能正常工作。

当我 运行 自解压存档时,它会正确自解压。所以我们有这个文件夹结构:

  • 一个文件夹JVM64,
  • 一个文件install.jar,
  • 一个文件setup.exe
  • 一个文件setup.ico.

但对于遇到问题的用户,它只会提取 JVM64:

 Volume in drive C has no label.
 Volume Serial Number is A663-4CEF

 Directory of C:\Users\gcdr\AppData\Local\Temp

14/08/2018  21:40    <DIR>          .
14/08/2018  21:40    <DIR>          ..
14/08/2018  21:40    <DIR>          RarSFX0
               0 File(s)              0 bytes

 Directory of C:\Users\gcdr\AppData\Local\Temp\RarSFX0

14/08/2018  21:40    <DIR>          .
14/08/2018  21:40    <DIR>          ..
14/08/2018  21:40    <DIR>          JVM64
               0 File(s)              0 bytes

我发现一位用户禁用 Norton AntiVirus 允许安装。
现在我习惯将每个新版本提交到诺顿白名单,但那个选项已经消失了。

为什么会这样?名为 install.jar 的文件是否有一些限制?

我花了一段时间才弄清楚 运行 在 SFX 存档 songkong-windows64.exe 上到底发生了什么。

首先我检测到临时目录 %TEMP%\RarSFX0 仍然存在,尽管它应该在安装完成后被 SFX 存档开头的 SFX 模块删除,无论是否真正安装了应用程序。这是 SFX 模块根据存档注释文件中的 SFX 脚本命令执行的 setup.exe 出现问题的第一个迹象,内容为:

;The comment below contains SFX script commands

Setup=setup.exe
TempMode
Title=Unpacking SongKong Installer

所以我在包含 setup.exe 的目录中创建了一个批处理文件,其中包含以下两行:

@setup.exe
@echo Exit code is: %ERRORLEVEL%

我可以看到从命令提示符 window 中执行批处理文件时禁用了用户帐户控制(没有提示就完全授予管理权限)对话框 window 选择安装语言和同时在命令提示符 window 行中:

Exit code is: 0

这表明 setup.exe 已经终止,尽管安装根本没有完成。所以它看起来 setup.exe 只是一个小的启动器应用程序,它并不真正进行安装并在安装完成甚至真正开始之前自行终止。那可不好。

我使用了下一个免费的 Sysinternals Process Monitor 并查看了此工具在 运行ning songkong-windows64.exe 上记录的文件系统访问并确认了我的假设:setup.exe 只是 运行s JVM64\bin\javaw.exe 参数 -jarinstall.jar 在 SFX 模块创建的文件夹中 RarSFX0, RarSFX1, ...

WinRAR 的帮助中写的关于使用 TempMode 进行 SFX 存档的内容非常糟糕。

后可以阅读
  • 单击 运行ning WinRAR 最后一个菜单 帮助 第一个菜单项 帮助主题,
  • 单击第一个选项卡上的下一步 Contents 左边的 [+] 符号以列出项目 自解压模块,
  • 双击子列表项 GUI SFX 模块:设置命令
  • 点击 link TempMode:

In TempMode SFX needs to detect the termination of setup program to delete temporary files. Such approach works correctly if setup program is not terminated before installation is done. But sometimes the setup program starts a child process and terminates, expecting a child process to complete installation. In such case SFX deletes temporary files immediately after detecting that main setup application is finished, resulting in malfunctioning child process. So TempMode works correctly only with those setup programs, which do not start another processes or, at least, are not terminated until all child processes are finished.

本段清楚地描述了使用 TempMode 执行的应用程序不应在整个安装过程完成之前自行终止。但是 setup.exe 并没有满足这个非常重要的要求,它在开始真正的安装过程后立即终止。

SFX 模块尝试删除临时目录 RarSFX0,但 Windows 阻止了此操作,因为 JVM64\bin\javaw.exe 仍然是 运行ning 而 install.jar 是当前由 Java 可执行文件打开。好吧,根据 CPU 和硬盘性能,目录 RarSFX0 中的所有文件(包括 install.jar 可能在 javaw.exe 真正完成并打开此可执行文件之前就已被删除文件 install.jar 而子目录 JVM64 绝对不能删除,因为 javaw.exe 此时总是 运行ning 或被防病毒应用程序扫描有害代码。

解决方案根本不使用启动器应用程序 setup.exe,而是 运行ning javaw.exe 直接通过 SFX 模块使用所需的参数。

让我们假设目录 C:\Temp 包含:

  • 松空64
    • JVM64 ... 及其所有子目录和文件
    • CreateSFX.bat
    • install.jar
    • setup.exe
    • setup.ico

批处理文件 CreateSFX.bat 包含以下命令行:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceFolder=%~dp0"
set "SourceFolder=%SourceFolder:~0,-1%"
set "CommentFile=%SourceFolder%\Setup.txt"
for %%I in ("%SourceFolder%") do set "ArchiveFile=%%~dpIsongkong-windows64.exe"

if not exist "%CommentFile%" (
    echo ;The comment below contains SFX script commands
    echo/
    echo Setup=JVM64\bin\javaw.exe -jar install.jar
    echo TempMode
    echo Title=Unpacking SongKong Installer
)>"%CommentFile%"

del "%ArchiveFile%" 2>nul

rem Create solid RAR5 SFX archive using best compression with 64 MB dictionary size.
echo Create RAR SFX, please wait ...
"%ProgramFiles%\WinRAR\WinRar.exe" a -@ -afrar -cfg- -ep1 -ibck -iicon"%SourceFolder%\setup.ico" -k -m5 -ma5 -md64m -r -s -sfx"%ProgramFiles%\WinRAR\SfxModule\Default64.sfx" -x"%SourceFolder%\Setup.*" -x"%~f0" -tl -y -z"%CommentFile%" -- "%ArchiveFile%" "%SourceFolder%\"

rem Create ZIP SFX archive using best compression.
rem echo Create ZIP SFX, please wait ...
rem "%ProgramFiles%\WinRAR\WinRar.exe" a -@ -afzip -cfg- -ep1 -ibck -iicon"%SourceFolder%\setup.ico" -m5 -r -sfx"%ProgramFiles%\WinRAR\Zip64.sfx" -x"%SourceFolder%\Setup.*" -x"%~f0" -tl -y -z"%CommentFile%" -- "%ArchiveFile%" "%SourceFolder%\"
endlocal

如果此文件不存在,此批处理文件会在执行时创建包含以下内容的文件 C:\Temp\SongKong64\Setup.txt

;The comment below contains SFX script commands

Setup=JVM64\bin\javaw.exe -jar install.jar
TempMode
Title=Unpacking SongKong Installer

此处重要的是不同的 Setup SFX 脚本命令。使用参数 -jarinstall.jar 指示 SFX 模块 运行 JVM64\bin\javaw.exe 而不是 setup.exe。 SFX模块在运行宁javaw.exe之前用相对路径使临时目录成为当前目录。

然后批处理文件 运行s WinRAR.exe 创建 SFX 存档 C:\Temp\songkong-windows64.exe 排除 C:\Temp\SongKong64 中的所有 Setup.* 文件以及批处理文件 CreateSFX.bat.

使用 English WinRAR 5.60 使用选项创建的 RAR5 SFX 压缩文件的文件大小为 111 MiB.

批处理文件还包含用于创建文件大小为 133 MiB 的 ZIP SFX 存档的命令行。

在运行使用此批处理文件创建的 SFX 存档时,用于选择安装语言的对话框 window 打开,并且在显示此 window 时没有文件被删除。单击 X 按钮取消安装时,SFX 模块检测到 javaw.exe 终止并按预期删除临时目录 RarSFX0

我从来没有完成安装,但它应该像这里写的那样工作。我无法通过 Process Monitor 看到 setup.exe 定义特殊环境变量或修改 javaw.exe.

的当前目录

如果 javaw.exe 应该 运行 具有本地管理员的提升权限,则可以添加 WinRAR 开关 -iadm创建一个 SFX 存档,在 Windows Vista 及更高版本中启动时请求管理访问权限。

有关使用开关的帮助,在 WinRAR 的帮助下从 Contents 选项卡通过 命令行模式 开关 帮助页面 字母开关列表 并单击上面使用的开关从上到下阅读详细说明。

要了解批处理文件中使用的命令及其工作原理,请打开命令提示符 window,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。

  • call /? 解释 %~dp0 ... 以反斜杠结尾的批处理文件的驱动器和路径,将在下一个命令行中删除。
  • del /?
  • endlocal /?
  • for /?
  • if /?
  • rem /?
  • set /?
  • setlocal /?