You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Java(8)应用中访问Wix构建的MSI公共属性?

搞定MSI安装传参到JavaFX应用的方法

我来一步步帮你实现这个需求,核心思路是让MSI接收命令行参数,把参数值存到注册表(或者你偏好的存储位置),然后Java应用从这个存储位置读取值就行。

1. 修改你的自定义WXS文件

首先得在WXS里做两处关键修改:让MSI能接收FOO参数,然后把这个参数值写到注册表。

1.1 定义可接收的命令行属性

在你的src/main/deploy/package/windows/<<APPNAME>>.wxs的<Product>标签里,加一行定义FOO属性,这样安装时传的FOO=BAR才能被MSI识别:

<Property Id="FOO" Value="" />
<!-- 空值是默认值,安装时可以用命令行覆盖 -->

1.2 把FOO的值写到注册表

接下来要把这个值存到注册表,这样Java应用能读到。找到你现有注册表相关的代码块(或者新增一个组件),添加存储FOO的注册表项:

<DirectoryRef Id="APPLICATIONFOLDER">
  <Component Id="AppRegistryConfig" Guid="这里生成一个新的GUID哦">
    <RegistryKey Root="REGISTRY_ROOT" Key="SOFTWARE\APPLICATION_VENDOR\APPLICATION_NAME" Action="createAndRemoveOnUninstall">
      <!-- 保留你原来的Path注册表项,这是你之前代码里有的 -->
      <RegistryValue Name="Path" Type="string" Value="[APPLICATIONFOLDER]" KeyPath="yes" />
      <!-- 新增这行,把FOO的值存进去 -->
      <RegistryValue Name="FOO" Type="string" Value="[FOO]" />
    </RegistryKey>
  </Component>
</DirectoryRef>

1.3 确保组件被安装

别忘记把这个新的注册表组件加到<Feature>里,不然安装时不会执行这个组件的逻辑:

<Feature Id="MainApplication" Title="Main Application" Level="1">
  <ComponentRef Id="AppRegistryConfig" />
  <!-- 这里保留你原来的其他ComponentRef,比如主程序文件的引用 -->
</Feature>

可选:解决参数传递问题(如果遇到的话)

如果安装后发现FOO的值没存进去,可以试试把FOO加入安全属性列表,确保参数能在安装流程中传递:

<Property Id="SecureCustomProperties" Value="FOO" />

2. 重新打包MSI

用javafxpackager重新构建你的MSI包,确保自定义WXS被正确加载:

javafxpackager -deploy -native msi -srcdir dist -srcfiles your-app.jar -outdir target -outfile YourApp -name "YourApp" -vendor "YourVendor" -version 1.0.0

3. 在JavaFX应用里读取FOO的值

现在就可以在应用里通过Java的Preferences类读取注册表的值了,根据你的安装范围(全局/当前用户)选择对应的读取方式:

3.1 全局安装(InstallScope="perMachine",对应注册表HKLM)

import java.util.prefs.Preferences;

public class AppConfig {
    public static String getFooValue() {
        // 对应注册表路径:HKEY_LOCAL_MACHINE\SOFTWARE\你的厂商名\你的应用名
        Preferences systemPrefs = Preferences.systemRoot()
                .node("/SOFTWARE/APPLICATION_VENDOR/APPLICATION_NAME");
        // 如果没找到FOO的值,就返回"default"作为默认值
        return systemPrefs.get("FOO", "default");
    }

    // 在你的应用初始化时调用这个方法就行
    public static void main(String[] args) {
        System.out.println("FOO的值是:" + getFooValue());
    }
}

3.2 当前用户安装(InstallScope="perUser",对应注册表HKCU)

只需要把上面的Preferences.systemRoot()换成Preferences.userRoot():

Preferences userPrefs = Preferences.userRoot()
        .node("/SOFTWARE/APPLICATION_VENDOR/APPLICATION_NAME");

注意32位/64位兼容性

如果你的JRE是32位,而MSI是64位(或者反过来),注册表会自动映射到Wow6432Node目录下,这时候要调整路径:

// 32位JRE读取64位MSI的注册表
Preferences systemPrefs = Preferences.systemRoot()
        .node("/SOFTWARE/Wow6432Node/APPLICATION_VENDOR/APPLICATION_NAME");

测试一下

安装的时候用这个命令:msiexec /i YourApp.msi FOO=BAR /qn(/qn是静默安装,不想静默就去掉),然后启动应用,调用getFooValue(),应该就能拿到BAR啦!

内容的提问来源于stack exchange,提问作者Pablo Fernandez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:03:34