如何为 Java 程序创建 MSI Windows 安装程序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29748422/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 15:51:03  来源:igfitidea点击:

How to create a MSI Windows installer for a Java program?

javawixwindows-installer

提问by gouessej

I'd like to create a single Microsoft Installer file for a Java program. I can't use Netbeans or any Maven plugin to do it because I can't use Oracle Java and/or JavaFX (mainly for legal reasons) and both seem to use Oracle native deployment + JavaSE 1.8.

我想为 Java 程序创建一个 Microsoft 安装程序文件。我无法使用 Netbeans 或任何 Maven 插件来执行此操作,因为我无法使用 Oracle Java 和/或 JavaFX(主要是出于法律原因)并且两者似乎都使用 Oracle 本机部署 + JavaSE 1.8。

My current archivecontains:

我当前的档案包含:

  • a Java Runtime Environment (OpenJDK 1.7 JRE)
  • a script (.bat)
  • a fat JAR
  • an icon file
  • a few text files
  • Java 运行时环境 (OpenJDK 1.7 JRE)
  • 一个脚本 (.bat)
  • 一个胖罐子
  • 一个图标文件
  • 几个文本文件

I don't want to use the JRE of the system, that's why I provide another JRE. The script just calls the JRE with a few arguments. The icon file is in .ico format. The fat JAR is the JAR containing all necessary Java classes, native libraries and assets, including the third party libraries.

我不想使用系统的JRE,这就是我提供另一个JRE的原因。该脚本仅使用一些参数调用 JRE。图标文件为 .ico 格式。胖 JAR 是包含所有必需的 Java 类、本机库和资产(包括第三方库)的 JAR。

I'd like to allow the end user to install, run and uninstall my program. I want to provide one shortcut in the start menu to run it and another one to uninstall it. It seems to be explained here. Do I have to use anything else to create a shortcut to uninstall my program?

我想允许最终用户安装、运行和卸载我的程序。我想在开始菜单中提供一个快捷方式来运行它,另一个快捷方式来卸载它。这里好像有说明。我是否必须使用其他任何东西来创建快捷方式来卸载我的程序?

I've looked at Wix Toolset for several weeks. I understand that I have to write a wxs file to use with "candle.exe", it creates a wixobj file, I have to run "light.exe" with this file and I get a MSI file.

我已经研究 Wix 工具集好几个星期了。我知道我必须编写一个 wxs 文件来与“candle.exe”一起使用,它会创建一个 wixobj 文件,我必须用这个文件运行“light.exe”,然后我才能得到一个 MSI 文件。

I know how to add a file, it's explained herebut I don't know how to add the whole directory containing the JRE without mentioning each file one by one. How can it be done in the wxs file?

我知道如何添加文件,这里有解释但我不知道如何添加包含 JRE 的整个目录而不一一提及每个文件。如何在wxs文件中完成?

How to pick some unique GUIDs?

如何选择一些独特的 GUID?

Is there already a (more?) simple tool that I can use to make a MSI file from a fat JAR? I prefer understanding how to build such a file in command line under Windows first before trying to do the same programmatically with Apache POI under GNU Linux.

是否已经有一个(更多?)简单的工具可以用来从胖 JAR 制作 MSI 文件?在尝试在 GNU Linux 下使用 Apache POI 以编程方式执行相同操作之前,我更喜欢先了解如何在 Windows 下的命令行中构建这样的文件。

Edit.: This is my first wxs file:

编辑。:这是我的第一个 wxs 文件:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Product Id="*" Name="Truly Unusual Experience of Revolution" Language="1033" Version="0.0.0.0" Manufacturer="Julien Gouesse" UpgradeCode="00000000-0000-0000-0000-000000000000">
    <!-- Installer's Icon in Add/Remove Programs -->
 <Icon Id="icon.ico" SourceFile="tuerLogo.ico"/>
    <Property Id="ARPPRODUCTICON" Value="icon.ico" />
 <!-- Installer's version = 200 because the 64-bit support is required -->
    <Package InstallerVersion="200" InstallPrivileges="elevated" InstallScope="perMachine" Compressed="yes" Platform="x64" />
    <Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />
    <MajorUpgrade AllowDowngrades="yes" IgnoreRemoveFailure="yes" Schedule="afterInstallInitialize" />
    <Condition Message="This application is only supported on Windows XP, Windows Vista, Windows Server 2008, or higher.">
      <![CDATA[Installed OR (VersionNT >= 501)]]>
    </Condition>
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="APPLICATIONROOTDIRECTORY" Name="Truly Unusual Experience of Revolution">
    <Component Id="tuer.bat" Guid="00000000-0000-0000-0000-000000000000">
            <File Id="tuer.bat" Source="tuer.bat" KeyPath="yes"/>
    </Component>
    <Component Id="tuer.jar" Guid="00000000-0000-0000-0000-000000000000">
            <File Id="tuer.jar" Source="tuer.jar" KeyPath="yes"/>
    </Component>
    <Component Id="LICENSE.txt" Guid="00000000-0000-0000-0000-000000000000">
            <File Id="LICENSE.txt" Source="LICENSE.txt" KeyPath="yes"/>
    </Component>
    <Component Id="NOTICE.txt" Guid="00000000-0000-0000-0000-000000000000">
            <File Id="NOTICE.txt" Source="NOTICE.txt" KeyPath="yes"/>
    </Component>
    <Component Id="README.txt" Guid="00000000-0000-0000-0000-000000000000">
            <File Id="README.txt" Source="README.txt" KeyPath="yes"/>
    </Component>
  </Directory>
      </Directory>
   <Directory Id="ProgramMenuFolder">
        <Directory Id="ApplicationProgramsFolder" Name="Truly Unusual Experience of Revolution"/>
      </Directory>
 </Directory>
 <!-- Shortcut in the Start Menu -->
 <DirectoryRef Id="ApplicationProgramsFolder">
      <Component Id="ApplicationShortcut" Guid="00000000-0000-0000-0000-000000000000">
        <Shortcut Id="ApplicationStartMenuShortcut" 
                  Name="Truly Unusual Experience of Revolution" 
                  Description="First person shooter"
                  Target="[#tuer.bat]"
                  WorkingDirectory="APPLICATIONROOTDIRECTORY"
         Icon="icon.ico" />
          <RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
          <RegistryValue Root="HKCU" Key="Software\Microsoft\TrulyUnusualExperienceofRevolution" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
      </Component>
    </DirectoryRef>
    <Feature Id="TrulyUnusualExperienceofRevolution" Title="Truly Unusual Experience of Revolution" Level="1">
   <ComponentRef Id="tuer.bat" />
   <ComponentRef Id="tuer.jar" />
   <ComponentRef Id="LICENSE.txt" />
   <ComponentRef Id="NOTICE.txt" />
   <ComponentRef Id="README.txt" />
   <ComponentRef Id="ApplicationShortcut" />
 </Feature>
  </Product>
</Wix>

Edit.2: Thisis the file obtained by running "heat" on the JRE directory.

Edit.2:是在JRE目录上运行“heat”得到的文件。

N.B:I don't answer to my own question but I stopped investigating when I discovered that building an installer with NSIS (Nullsoft Scriptable Install System) would be a lot easier because there are already an Ant taskand some packages for several GNU Linux distros (including Mageia, Fedora, ...) to make it work. You can find a script called Java Launcherto look for a JRE in your software and in your operating system (even though I advise you to bundle an OpenJDK JRE in your software to ensure that it will go on working despite the updates or the absence of a JRE in the operating system), another script with automatic JRE installationand a rudimentary example of nsi script for a Java based software.

注意:我没有回答我自己的问题,但是当我发现使用 NSIS(Nullsoft Scriptable Install System)构建安装程序会容易得多时,我停止了调查,因为已经有一个 Ant 任务和一些用于几个 GNU Linux 发行版的包(包括Mageia、Fedora 等)使其工作。您可以找到一个名为Java Launcher的脚本来查找您的软件和操作系统中的 JRE(尽管我建议您在您的软件中捆绑一个 OpenJDK JRE,以确保它在更新或缺少操作系统中的一个 JRE),另一个自动安装 JRE 的脚本基于 Java 的软件的 nsi 脚本的基本示例

P.S: By the way, I now use my own tool (which uses Redline RPM under the hood), it's fully documented, open source (under GPL), and works for RPM, DEB, APP and EXE (via NSIS) too, it's called Java Native Deployment Toolkit.

PS:顺便说一句,我现在使用我自己的工具(它在引擎盖下使用 Redline RPM),它有完整的文档记录,开源(在 GPL 下),并且也适用于 RPM、DEB、APP 和 EXE(通过 NSIS),它是称为Java 本机部署工具包

回答by jewelsea

The javapackagerfrom the OpenJDK project for Java 8/9 includes the ability to package MSI installers (using WIX) that include custom JRE installations for the installed application. If you don't wish to use the packager provided with Oracle Java or one that you compile from the OpenJDK source, maybe reviewing the javapackager source codemight help you to create your own packaging utilities.

来自 Java 8/9 的 OpenJDK 项目的javapackager包括打包 MSI 安装程序(使用 WIX)的能力,其中包括已安装应用程序的自定义 JRE 安装。如果您不希望使用 Oracle Java 提供的打包程序或从 OpenJDK 源代码编译的打包程序,也许查看javapackager 源代码可能会帮助您创建自己的打包实用程序。

Licensing seems to be a concern for you - so if you adopt this path, you can check that the OpenJDK legal documentsare amenable to your situation. Note that if you use OpenJDK, the Oracle BCLis not applicable.

许可似乎是您关心的问题 - 因此,如果您采用此路径,则可以检查OpenJDK 法律文档是否适合您的情况。请注意,如果您使用 OpenJDK,则Oracle BCL不适用。

I have not checked the javapackager source in detail, but it may have some reliance on Java 8 features. As your target is to create a JRE 7 based package, you might be able to use a Java 8 runtime to execute the packager, but package a Java 7 JRE as a target. If you must run the packaging tools using a Java 7 runtime and the packager code uses Java 8 features - you could fork it and backport it to Java 7 (you would need some pretty strict requirements to require this - most people would not have such requirements).

我没有详细检查 javapackager 源代码,但它可能对 Java 8 功能有一些依赖。由于您的目标是创建基于 JRE 7 的包,因此您可以使用 Java 8 运行时来执行打包程序,但将 Java 7 JRE 打包为目标。如果您必须使用 Java 7 运行时运行打包工具并且打包程序代码使用 Java 8 功能 - 您可以将其分叉并将其向后移植到 Java 7(您需要一些非常严格的要求来要求这样做 - 大多数人不会有这样的要求)。

I'm not recommending the above as the most ideal way to accomplish your task - I'm just throwing out some ideas which might or might not be useful to you.

我不推荐上述作为完成任务的最理想方式 - 我只是抛出一些可能对您有用也可能没有用的想法。

回答by Christopher Painter

I run an opensource project called IsWiXthat handles this scenario. You can watch a video (linked below) for creating an MSI for a WPF .NET desktop application.

我运行一个名为IsWiX的开源项目来处理这种情况。您可以观看为 WPF .NET 桌面应用程序创建 MSI 的视频(链接如下)。

The concepts are the same for a Java application. You just deploy a private instance of the JRE along with your application and create a shortcut that points to the .BAT file. About the only thing you would do custom is create an Icon element that points to your ICO file and set an attribute on the Shortcut element to point to the icon. In the compiled code world we don't have to do this as the shortcut will automatically display the default icon resource in the target executable.

Java 应用程序的概念是相同的。您只需将 JRE 的私有实例与您的应用程序一起部署,并创建一个指向 .BAT 文件的快捷方式。您唯一要做的就是创建一个指向您的 ICO 文件的 Icon 元素,并在 Shortcut 元素上设置一个属性以指向该图标。在已编译的代码世界中,我们不必这样做,因为快捷方式将自动显示目标可执行文件中的默认图标资源。

A little write up on the video can be found here:

可以在此处找到有关视频的一些内容:

Building and Deploying a Windows Desktop Application using IsWiX

使用 IsWiX 构建和部署 Windows 桌面应用程序

And the (silent) video itself:

和(无声)视频本身:

Building and Deploying a Windows Desktop Application using IsWiX

使用 IsWiX 构建和部署 Windows 桌面应用程序

回答by haferblues

Just stumbled upon this question. Maybe my two cents can help. I use two maven plugins together:

刚刚偶然发现了这个问题。也许我的两分钱可以提供帮助。我一起使用两个 Maven 插件:

1) launch4j-maven-plugin (com.akathist.maven.plugins.launch4j) used to wrap the jar inside an exe file. It also allows to specify a minimum java version. That way, you don't have to ship the java version with the msi (which then has to be updated from time to time), but just redirect the user to the java download page (lightweight solution). Launch4J has a bunch of other features, which makes your java application look nicer f.i. a SplashScreen or you can pass startup params, which is nice. That way you can build very custom installers just by setting some properties in the pom.xml

1)launch4j-maven-plugin(com.akathist.maven.plugins.launch4j)用于将jar包在一个exe文件中。它还允许指定最低 Java 版本。这样,您不必随 msi 一起提供 java 版本(然后必须不时更新),而只需将用户重定向到 java 下载页面(轻量级解决方案)。Launch4J 有很多其他功能,这使您的 Java 应用程序在 SplashScreen 上看起来更好,或者您可以传递启动参数,这很好。这样你就可以通过在 pom.xml 中设置一些属性来构建非常自定义的安装程序

2) wix-maven-plugin (org.bitbucket.joxley) Since we have an exe now we can create a very nice installer, with desktop shortcuts and a "launch now" checkbox at the end of the installation process.

2) wix-maven-plugin (org.bitbucket.joxley) 由于我们现在有一个 exe,我们可以创建一个非常好的安装程序,在安装过程结束时带有桌面快捷方式和“立即启动”复选框。

This combination is not the easiest one to implement, but once it is in place you have countless options to build different versions of your software (Evaluation Copy/Pro Version) and to customize your software (e.g. different look and feel of the installer, even attaching a different software licence is possible). With the command line arguments set in the launch4J plugin you can create an app which starts in a certain state or with a certain configuration.

这种组合并不是最容易实现的,但是一旦到位,您就有无数的选择来构建不同版本的软件(评估副本/专业版)和自定义软件(例如,安装程序的不同外观和感觉,甚至附加不同的软件许可证是可能的)。使用 launch4J 插件中设置的命令行参数,您可以创建一个以特定状态或特定配置启动的应用程序。

We use the solution in production for several years now.

我们在生产中使用该解决方案已有好几年了。