install4j 的新功能

详细的变更列表请参阅更新日志。

install4j 13.12026-08-19更新日志

生成的启动器现在可以创建 AOT 缓存,从而显著缩短应用程序的启动时间。AOT 缓存是 HotSpot JVM 的一项特性,它将已加载和已链接的类存储到一个文件中,使 JVM 在后续运行时可以跳过大部分类加载工作。

在启动器向导新增的 “AOT 缓存”步骤中,选中 “首次运行时创建 AOT 缓存”。当应用程序在 Java 25 或更高版本上首次启动时,启动器会向 JVM 传递 -XX:AOTCacheOutput=<cache file>。这第一次运行相当于一次训练运行,JVM 会在退出时写入缓存。在后续运行中,缓存通过 -XX:AOTCache=<cache file> 传递。在 Java 24 及更低版本上不会传递任何 AOT 参数,因此同一个启动器可适用于所有 Java 版本。

截图截图

默认情况下,缓存存储在每用户的缓存目录中:在 Linux 和 Unix 上为 $XDG_CACHE_HOME/install4j/aot 或 ~/.cache/install4j/aot,在 macOS 上为 ~/Library/Caches/install4j/aot,在 Windows 上为 %LOCALAPPDATA%\install4j\aot。可以在启动器向导中配置自定义的基础路径。缓存文件名包含一个由应用程序构建和 Java 运行时共同派生的键,因此缓存会在应用程序更新和 Java 运行时变更后自动重新生成。先前构建的缓存会被自动清理,卸载程序也会删除该安装的缓存。

install4j IDE 本身同样使用了 AOT 缓存,现在启动速度提升了一倍以上。

新增的一组 YAML 操作让您无需编写任何脚本,即可在安装和卸载期间读取、修改和写入 YAML 配置文件。YAML 是云原生环境中占主导地位的配置格式,因此安装程序越来越需要在目标系统上调整 YAML 文件。

截图截图

共提供四个操作:

  • “从 YAML 文件读取值”将某个路径处的值读入安装程序变量。标量值保留其 YAML 类型,还可以选择将映射展开为每个顶级条目对应一个安装程序变量,从而轻松根据 YAML 文件中的某一节初始化配置表单。
  • “统计 YAML 文件中的条目”统计列表或映射的条目数,并将结果保存到安装程序变量中。
  • “修改 YAML 文件”在一个或多个 YAML 文件中更改、插入或删除某个路径处的值。编辑在文本层面进行,因此注释和格式均会保留。结合读取操作展开得到的变量及其“叠加安装程序变量”选项,无需脚本即可完成完整的读取-修改-写入流程。
  • “写入 YAML 文件”将一个值写入 YAML 文件,创建或覆盖该文件。
截图截图

所有操作都通过统一的路径语法来定位节点:$.key 定位映射键,$['key'] 定位包含点号或特殊字符的键,$[0] 定位列表索引。各片段可以组合使用,例如 $.servers[0].host。对于包含多个 YAML 文档的文件,可通过文档索引加以支持。

install4j 现在可以为随生成的媒体文件一同发布的 install4j 运行时组件创建 CycloneDX 软件物料清单(SBOM)。SBOM 会列出构件的全部软件组件及其版本和哈希值,使漏洞扫描器能够根据已知 CVE 检查您的安装程序,并让您的发布满足软件供应链方面的要求。

运行时 SBOM 涵盖 install4j 运行时:原生启动器和辅助程序、安装程序运行时及其捆绑的库。分发树中的库不包含在内。

截图截图

SBOM 生成在“常规设置->媒体文件选项”步骤中配置。有两种相互独立的输出方式:

  • 外部 SBOM 以 JSON 和 XML 格式写入到每个媒体文件旁边。对于名为 myapp_windows-x64_1_0.exe 的媒体文件,生成的文件名为 myapp_windows-x64_1_0.exe.install4j_runtime.cdx.json 和 myapp_windows-x64_1_0.exe.install4j_runtime.cdx.xml,因此可以将它们随发布一起上传到安全扫描器。
  • 嵌入式 SBOM 放置在安装内部,位于分发树中一个可配置的路径下,同样采用 JSON 或 XML 格式。如果该路径下没有文件,install4j 会在其中放置仅包含运行时的 SBOM。

如果嵌入式 SBOM 路径指向一个已有的 CycloneDX SBOM(例如您的构建为应用程序生成的 SBOM),install4j 会将其扩充,加入 install4j 运行时组件及其依赖关系图。现有内容会保留,BOM 版本号会递增,因此安装后的构件只包含一份完整的 SBOM。支持 1.2 至 1.7 的 CycloneDX 规范版本。

install4j 13.1 对整个代码库进行了一轮安全加固:涵盖安装程序运行时、原生启动器和辅助程序、编译器以及 IDE。

同一轮工作还带来了大量针对边缘情况的健壮性修复,这些边缘情况此前可能导致异常或输出损坏。最值得注意的修复列在变更日志中。

install4j 13.02026-06-03更新日志

install4j 13 现在可以构建 Windows MSIX 媒体文件。

MSIX 是用于 Windows 应用程序的现代打包格式。它也是 Microsoft Store 的原生软件包格式,并与 Microsoft Intune 等托管部署工具相集成。MSIX 软件包由 Windows 本身以完全可逆的方式安装和卸载,并且标准用户无需管理员权限即可安装。

MSIX 与 MSI 完全相互独立。对于 MSI,install4j 只是在自身生成的安装程序外面生成一个包装器。这是因为屏幕、操作和脚本等 install4j 概念无法无缝地映射到 MSI 模型中。而 MSIX 是声明式的,因此服务、文件关联和启动任务等概念可以直接转换为清单条目。

双击 .msix 文件或在 PowerShell 中运行 Add-AppxPackage 即可安装 MSIX 软件包,安装时不会运行任何 install4j 安装程序向导。

请注意,分发这种媒体文件类型时必须进行代码签名,因为未签名的 MSIX 软件包只能在 Windows 的开发人员模式下安装。

截图截图

所有 MSIX 专属设置都在媒体文件向导的专用子步骤中配置。在 “MSIX 选项”步骤中,设置包标识名称、软件包版本以及经过测试的最低和最高 Windows 版本。您还可以将某个启动器设置为登录启动器,它会在用户登录时自动运行,用户以后可以在 Windows 的“启动应用”设置中将其禁用。

截图截图

包图标在 “包图标”子步骤中进行自定义。它显示在 Windows 安装对话框中。可以为它设置背景颜色,使带有透明区域的图标获得一个不透明的磁贴。对于开始菜单和任务栏,则使用启动器向导中配置的图标。

截图截图

服务从生成的服务启动器中选择,并通过清单注册为 Windows 服务。启动类型和服务账户在 “服务”子步骤中针对每个启动器单独配置。

截图截图

文件关联将一个或多个文件扩展名绑定到某个启动器,这样双击此类文件时就会打开您的应用程序。对于每个关联,都可以配置描述、可选的 MIME 类型以及自定义图标。

截图截图

URL 协议处理器以相同的方式声明,从而将诸如 myapp:// 之类的自定义协议路由到启动器。两者都在“文件关联和 URL 处理器”子步骤中设置。

App URI 处理器让启动器能够处理特定主机的普通 https:// 链接。当打开匹配的链接时,Windows 可以将其路由到您的应用程序而不是浏览器。由于未经网站同意就不能声明其链接,因此该主机必须发布生成的 windows-app-web-link.json 文件并将其放在 /.well-known/ 路径下,其中列出您的软件包。

截图截图

应用执行别名让选定的启动器以各自可执行文件的名称出现在用户的 PATH 上,从而可以在命令提示符或“运行”对话框中按名称调用。这些别名的作用域仅限于相应的软件包,并随软件包一起删除。别名在 “PATH 上的应用程序”子步骤中选择。

截图截图

在自动更新方面,MSIX 软件包依赖于 Windows 内置的 App Installer 机制,而不是 install4j 的更新架构。所需的 .appinstaller 文件由 install4j 生成,之后 Windows 会定期检查托管 URL,从而在后台安装新的软件包版本。托管 URL 以及更新行为(例如检查频率和是否提示用户)在 “自动更新”子步骤中配置。

截图截图

为项目配置的所有语言都会自动在清单中声明。

软件开发正迅速走向代理化,日常工作中的很大一部分现在都由 AI 编码助手驱动。install4j 13 将安装程序编写纳入了这一工作流程。它附带一个 AI 代理技能,让编码助手能够读取、编辑和创建 install4j 项目文件,这样只需用自然语言描述一项更改,就能将其直接应用到项目中。这降低了构建和维护安装程序的门槛,项目文件也成为代理所处理的代码库中的又一个组成部分。

该技能是一个自包含的知识包。它打包了项目文件架构、全部可用 bean 类(屏幕、操作、表单组件、屏幕样式和小部件样式)的目录、可运行的示例项目、install4j API 以及完整的文档,全部采用对 AI 友好的格式,并附有常见工作流程的说明。有了它,助手就能对照准确的信息进行核实,而不必凭空猜测。

兼容的助手在接到与 install4j 相关的任务时会自行加载该技能。例如,当要求它为 hello 示例添加一个启动检查,以检测已安装的版本并在重复安装前给出提示时,助手会找到正确的注册表 API,将新操作插入项目文件,并确认项目仍然可以编译。

截图截图

要安装该技能,请点击工具栏中的 “安装 AI 技能”按钮。在该对话框中,可以将其写入您的 AI 代理的 skills 目录。支持的代理包括 Claude Code、Claude Desktop、Cursor、Codex CLI、Gemini CLI、OpenCode 和 Junie。

它可以全局安装,这样您机器上的每个项目都能使用它;也可以按项目安装,此时仅当代理从该项目运行时才可用。该技能根据您所使用的确切 install4j 版本生成,因此其架构、bean 目录和示例始终与您安装中的编译器相匹配。

截图截图

install4j 13 引入了 install4j 项目文件的 XML 架构。该架构(install4j.xsd)随附在 install4j 安装的 resource 目录中,以内联描述的方式记录了 .install4j 文件格式的每一个元素、属性和枚举值。它非常全面,涵盖 230 多个元素、450 个属性和 150 个枚举值,并配有约 600 条描述它们的文档条目。

在 XML 编辑器中将该架构与您的 .install4j 文件关联后,编辑时即可获得自动补全、内联文档和验证功能。此外,现在每当您从命令行编译时,项目文件都会依据该架构进行验证,从而能以精确的消息尽早发现结构性错误。

截图截图

全新的 install4j 测试 API 让您能够编写自动化的端到端测试,从测试 JVM 内部以 GUI 模式驱动安装程序 UI。该 API 与框架无关,因此可以从 JUnit、TestNG、Spock 或普通 main 方法中使用它。

会话通过以下会话构建器之一启动:InstallerSessionBuilder.forMediaFile(...) 用于测试生成的安装程序,UninstallerSessionBuilder.forInstallation(...) 用于测试卸载程序,InstallerApplicationSessionBuilder.forInstallation(...) 用于更新下载器等自定义安装程序应用。构建器选项包括超时时间、额外的命令行参数、系统属性、工作目录、日志文件,以及以进程内方式运行安装程序以便于断点调试的调试模式。

在会话中,您可以按 id 等待屏幕,使用“下一步”、“上一步”、“取消”和“完成”按钮进行导航,通过表单组件和对话框的强类型句柄进行交互,最后验证安装程序变量、安装目录、日志和退出代码:

InstallerSession session = InstallerSessionBuilder
    .forMediaFile(new File("media/myApp_windows-x64.exe"))
    .installationDirectory(targetDirectory)
    .start();

session.waitForScreenId("welcome").nextScreen();

// Accept the license, then fill in a custom form screen
session.currentScreen().checkBox("acceptCheckBox").setSelected(true);
session.currentScreen().nextScreen();
session.currentScreen().textField("port").setText("8443");
session.currentScreen().nextScreen();

// Modal dialogs can be handled when they appear
session.alert().clickYes();

session.currentScreen().finish();

// Verify the outcome after the installer has exited
int exitCode = session.awaitExit(Duration.ofMinutes(2));
assertEquals(0, exitCode);

对于 Kotlin 用户,API 附带了扩展函数,使其用法更加符合语言习惯。useSession { } 代码块会启动会话并自动将其关闭,onScreen 和 onAlert 等辅助函数会在屏幕或对话框上运行一个代码块,而 session["name"] 访问器则读取安装程序变量:

InstallerSessionBuilder
    .forMediaFile(File("media/myApp_windows-x64.exe"))
    .useSession {
        onScreen("welcome") { nextScreen() }
        onCurrentScreen {
            checkBox("acceptCheckBox").setSelected(true)
            nextScreen()
        }
        onAlert { clickYes() }
        onCurrentScreen { finish() }
        awaitExit()
    }

测试 API 以 com.install4j:install4j-test 为坐标发布到 Maven Central,同时也以 install4j-test.jar 的形式捆绑在您安装的 resource 目录中。

这些 GUI 测试甚至可以在 CI 中无头运行。在没有显示器的 Linux 上(例如 GitHub Actions 运行器),安装程序子进程会自动由 xvfb-run 包裹,并搭配一个轻量级窗口管理器,因此安装程序会被渲染到虚拟帧缓冲中,测试无需任何物理屏幕即可运行。机器上只需要有 xvfb-run 以及受支持的窗口管理器之一(metacity、mutter、openbox、fluxbox 或 marco)。

截图截图

控制台模式新增了富终端 UI。控制台模式是 install4j 安装程序在没有图形显示环境时的运行方式。以前的 install4j 版本仅支持纯文本控制台模式。

当安装程序以 Java 25 或更高版本在支持 ANSI 的终端中运行时,控制台模式现在会呈现一个现代的交互式 UI:

  • 彩色输出,让成功和错误消息更加醒目。
    截图截图
  • 实时进度条带有百分比显示,状态行和详细信息行原地更新而不是滚动掠过。较长的文件路径会在中间缩短,从而保持开头和结尾可见。
    截图截图
  • 旋转指示器,用于耗时未知的工作。
    截图截图
  • 单选列表可使用方向键导航,用于选项菜单以及“是/否”和“确定/取消”确认。
    截图截图
  • 通过复选框列表进行多选。
    截图截图
  • 文本和掩码密码输入,以及带有 Tab 补全的文件和目录提示。
    截图截图
  • 用于许可协议等长文本的内置翻页器,可选择要求用户滚动到末尾。
    截图截图

当在较旧的 Java 版本上运行,或者没有具备足够能力的终端时(例如输出被重定向到文件或通过管道传送给另一个进程时),富渲染器会自动回退到纯文本控制台。可以通过向安装程序传递 -J-Dinstall4j.plainConsole=true 来强制使用纯文本渲染器。

“标签”和“键值对”表单组件新增了 “省略文件路径”属性。当标签中包含的文件路径超出可用的水平空间时,路径的中间部分会被替换为省略号,从而使路径的开头和结尾保持可见。

截图截图

install4j IDE 现在支持完整的缩放。在常规设置中,您可以将缩放系数设置为百分比,也可以设置任意字号的自定义 UI 字体,UI 将随之进行相应的缩放。

截图截图

借助这一能力,install4j IDE 现在可以在 Linux 上搭配所有 OpenJDK 变体并以所有 HiDPI 分辨率运行。以前在 Linux 上,只有 JetBrains 运行时支持 HiDPI 分辨率。

新增了 用户主目录启动器变量。与其他 ${launcher:...} 变量一样,它由启动器在启动时自行展开(现在 Linux 上的 .vmoptions 文件中也支持),并解析为当前用户的主目录。

例如,这对于将 VM 参数或程序参数指向特定于用户的配置目录非常有用。

新增了对 JEP 512 中新 main 方法的支持。JEP 512(“紧凑源文件与实例 main 方法”)已在 Java 25 中定稿,它允许将 main 方法声明为实例方法,并省略 String[] 参数。

启动器现在可以指向入口点为实例 void main() 方法的类,此外也仍然支持经典的 public static void main(String[] args)。