Skip to content

Commit 584f963

Browse files
authored
Add Windows MSI packaging support
Update the ant build script (build.xml) and the GitHub build action (.github/workflows/build.yaml). Construct and add appropriate Windows icon file (icon.ico). Add explanation and instructions to readme file (README.md).
2 parents afb4db8 + 0f1ef53 commit 584f963

4 files changed

Lines changed: 63 additions & 7 deletions

File tree

.github/workflows/build.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
strategy:
1515
fail-fast: false
1616
matrix:
17-
os: [macos-latest, ubuntu-latest]
17+
os: [macos-latest, ubuntu-latest, windows-latest]
1818

1919
steps:
2020
- name: Checkout Code
@@ -61,6 +61,7 @@ jobs:
6161
files: |
6262
artifacts/*.dmg
6363
artifacts/*.deb
64+
artifacts/*.msi
6465
body: "Automatic build of ${{ github.ref_name }}"
6566
env:
6667
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

README.md

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# NativeJavaApp
22
Scaffold for creating double-clickable apps using Java
33

4-
This project uses Apache Ant and JDK 25 to compile, bundle, and package a Java application into native installers (.dmg for macOS and .deb for Ubuntu).
4+
This project uses Apache Ant and JDK 25 to compile, bundle, and package a Java application into native installers (.dmg for macOS, .deb for Ubuntu, and .msi for Windows).
55

66
## Common Requirements (All Systems)
77
Before running the build, ensure the following are installed and configured:
@@ -27,6 +27,16 @@ sudo apt install ant fakeroot dpkg-dev
2727
- fakeroot: Allows the package to be built with correct file permissions without requiring root access.
2828
- dpkg-dev: Provides the core utilities to create Debian packages.
2929
- Icon Asset: A file named icon.png (512x512 recommended) must be in the project root.
30+
## Windows Setup
31+
To build the .msi installer on Windows, ensure the following:
32+
- JDK 21 or 25: Must be installed with JAVA_HOME configured.
33+
- Apache Ant: Installed and available in your PATH.
34+
- WiX Toolset: Required by jpackage to create MSI installers.
35+
- Download and install from: https://wixtoolset.org/releases/
36+
- Version 3.11 or higher is recommended.
37+
- After installation, verify WiX is in your PATH by running: `candle -?`
38+
- Icon Asset: A file named icon.ico must be in the project root.
39+
- Note on Security: Windows may show a SmartScreen warning for unsigned installers. Users will need to click "More info" > "Run anyway" to install the app.
3040
## Project Directory Structure
3141
Ensure your project looks like this for the build.xml to find all resources:
3242

@@ -36,6 +46,7 @@ MyAppName/
3646
│ └── Main.java # Your source code
3747
├── icon.icns # Required for macOS DMG
3848
├── icon.png # Required for Ubuntu DEB
49+
├── icon.ico # Required for Windows MSI
3950
└── build.xml # The Ant build script
4051
```
4152
## Usage Commands
@@ -44,7 +55,7 @@ Open your terminal in the project root and use the following targets:
4455
| Command | Description |
4556
|-----|-----|
4657
| ant | The default; runs the package target. |
47-
| ant package | Automatically detects OS and builds .dmg (Mac) or .deb (Linux). |
58+
| ant package | Automatically detects OS and builds .dmg (Mac), .deb (Linux), or .msi (Windows). |
4859
| ant run | Compiles and launches the app immediately for testing. |
4960
| ant clean | Deletes the build/ and dist/ folders to start fresh. |
5061
| ant -p | Displays a help menu of all available targets. |
@@ -58,6 +69,10 @@ Open your terminal in the project root and use the following targets:
5869
<td>Linux Icon Error: </td>
5970
<td>If the Linux build fails, ensure icon.png is not just a renamed .icns or .jpg. It must be a valid PNG file.</td>
6071
</tr>
72+
<tr>
73+
<td>Windows "candle.exe not found": </td>
74+
<td>Install WiX Toolset 3.11+ and ensure it's in your PATH. jpackage uses WiX to create MSI installers on Windows.</td>
75+
</tr>
6176
<tr>
6277
<td>Permissions: </td>
6378
<td>If the generated .app or .deb won't execute, ensure you have the necessary write permissions in the dist/ directory.</td>
@@ -69,8 +84,8 @@ This project uses GitHub Actions to automatically build and distribute native in
6984

7085
### The Build Phase (Continuous Integration)
7186
Every time you push code to the main branch or open a Pull Request:
72-
- GitHub starts a macOS runner and an Ubuntu runner.
73-
- Both systems compile the code and create their respective installers (.dmg and .deb).
87+
- GitHub starts a macOS runner, an Ubuntu runner, and a Windows runner.
88+
- All systems compile the code and create their respective installers (.dmg, .deb, and .msi).
7489
- The installers are saved as Artifacts in the GitHub Actions run summary for 90 days.
7590
### The Release Phase (Continuous Deployment)
7691
A formal GitHub Release is only triggered when you push a version tag.
@@ -92,6 +107,7 @@ git push origin v1.0.1
92107
- Under Assets, you will find:
93108
- MyAntApp-Installer.dmg (for macOS)
94109
- MyAntApp-Linux.deb (for Ubuntu/Debian)
110+
- MyAntApp-Windows.msi (for Windows)
95111

96112
### Changing the Version Number
97113
When ready to bump the version, remember to update the version number in **two** places to keep everything in sync:

build.xml

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,22 @@
3333
</and>
3434
</condition>
3535

36-
<condition property="icon.file" value="icon.icns" else="icon.png">
36+
<condition property="isWindows">
37+
<os family="windows"/>
38+
</condition>
39+
40+
<condition property="icon.file" value="icon.icns">
3741
<isset property="isMac"/>
3842
</condition>
43+
<condition property="icon.file" value="icon.ico">
44+
<and>
45+
<isset property="isWindows"/>
46+
<not><isset property="icon.file"/></not>
47+
</and>
48+
</condition>
49+
<condition property="icon.file" value="icon.png">
50+
<not><isset property="icon.file"/></not>
51+
</condition>
3952

4053
<target name="preflight" description="Print toolchain/OS info">
4154
<echo message="Java: ${java.runtime.name} ${java.runtime.version}"/>
@@ -94,9 +107,10 @@
94107
</javadoc>
95108
</target>
96109

97-
<target name="package" description="Build the native installer for the current OS (DMG or DEB)">
110+
<target name="package" description="Build the native installer for the current OS (DMG, DEB, or MSI)">
98111
<antcall target="dmg"/>
99112
<antcall target="debian"/>
113+
<antcall target="windows"/>
100114
</target>
101115

102116
<target name="dmg" depends="jar" if="isMac" description="[Mac Only] Builds the .dmg installer">
@@ -148,4 +162,29 @@
148162
<echo message="Success! Debian Package: ${dist.dir}/${app.name}-Linux.deb"/>
149163
</target>
150164

165+
<target name="windows" depends="jar" if="isWindows" description="[Windows Only] Builds the .msi installer">
166+
<mkdir dir="${dist.dir}"/>
167+
<exec executable="jpackage" failonerror="true">
168+
<arg value="--input"/><arg value="${jar.dir}"/>
169+
<arg value="--dest"/><arg value="${dist.dir}"/>
170+
<arg value="--name"/><arg value="${app.name}"/>
171+
<arg value="--main-jar"/><arg value="${app.name}.jar"/>
172+
<arg value="--main-class"/><arg value="${main.class}"/>
173+
<arg value="--type"/><arg value="msi"/>
174+
<arg value="--icon"/><arg value="${icon.file}"/>
175+
<arg value="--app-version"/><arg value="${app.version}"/>
176+
<arg value="--win-dir-chooser"/>
177+
<arg value="--win-shortcut"/>
178+
<arg value="--win-menu"/>
179+
</exec>
180+
<move todir="${dist.dir}">
181+
<fileset dir="${dist.dir}">
182+
<include name="${app.name}*.msi"/>
183+
<exclude name="${app.name}-Windows.msi"/>
184+
</fileset>
185+
<mapper type="merge" to="${app.name}-Windows.msi"/>
186+
</move>
187+
<echo message="Success! Windows Installer: ${dist.dir}/${app.name}-Windows.msi"/>
188+
</target>
189+
151190
</project>

icon.ico

151 KB
Binary file not shown.

0 commit comments

Comments
 (0)