Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
703 views
in Technique[技术] by (71.8m points)

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

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.

My current archive contains:

  • a Java Runtime Environment (OpenJDK 1.7 JRE)
  • a script (.bat)
  • a fat JAR
  • an icon file
  • a few text files

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.

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.

I know how to add a file, it's explained here but 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?

How to pick some unique GUIDs?

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.

Edit.: This is my first wxs file:

<?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="SoftwareMicrosoftTrulyUnusualExperienceofRevolution" 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>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The javapackager from 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 code might help you to create your own packaging utilities.

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

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).

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...