Skip to content

Commit 454235b

Browse files
committed
A msi merge module generation
1 parent ef8ecce commit 454235b

File tree

9 files changed

+133
-46
lines changed

9 files changed

+133
-46
lines changed

src/main/java/io/github/fvarrui/javapackager/maven/CreateWindowsExe.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
import org.twdata.maven.mojoexecutor.MojoExecutor.Element;
1919

2020
import io.github.fvarrui.javapackager.model.WindowsConfig;
21+
import io.github.fvarrui.javapackager.packagers.ArtifactGenerator;
2122
import io.github.fvarrui.javapackager.packagers.Context;
2223
import io.github.fvarrui.javapackager.packagers.Packager;
23-
import io.github.fvarrui.javapackager.packagers.ArtifactGenerator;
2424
import io.github.fvarrui.javapackager.packagers.WindowsPackager;
2525

2626
/**

src/main/java/io/github/fvarrui/javapackager/model/WindowsConfig.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public class WindowsConfig implements Serializable {
3232
private boolean createDesktopIconTask = true;
3333
private boolean generateSetup = true;
3434
private boolean generateMsi = true;
35+
private boolean generateMsm = false;
3536
private String msiUpgradeCode;
3637
private boolean wrapJar = true;
3738
private LinkedHashMap<String, String> setupLanguages = new LinkedHashMap<>();
@@ -195,6 +196,14 @@ public boolean isGenerateMsi() {
195196
public void setGenerateMsi(boolean generateMsi) {
196197
this.generateMsi = generateMsi;
197198
}
199+
200+
public boolean isGenerateMsm() {
201+
return generateMsm;
202+
}
203+
204+
public void setGenerateMsm(boolean generateMsm) {
205+
this.generateMsm = generateMsm;
206+
}
198207

199208
public String getMsiUpgradeCode() {
200209
return msiUpgradeCode;
@@ -229,8 +238,9 @@ public String toString() {
229238
+ ", txtFileVersion=" + txtFileVersion + ", txtProductVersion=" + txtProductVersion
230239
+ ", disableDirPage=" + disableDirPage + ", disableProgramGroupPage=" + disableProgramGroupPage
231240
+ ", disableFinishedPage=" + disableFinishedPage + ", createDesktopIconTask=" + createDesktopIconTask
232-
+ ", generateSetup=" + generateSetup + ", generateMsi=" + generateMsi + ", msiUpgradeCode="
233-
+ msiUpgradeCode + ", wrapJar=" + wrapJar + ", setupLanguages=" + setupLanguages + "]";
241+
+ ", generateSetup=" + generateSetup + ", generateMsi=" + generateMsi + ", generateMsm=" + generateMsm
242+
+ ", msiUpgradeCode=" + msiUpgradeCode + ", wrapJar=" + wrapJar + ", setupLanguages=" + setupLanguages
243+
+ "]";
234244
}
235245

236246
/**

src/main/java/io/github/fvarrui/javapackager/packagers/Context.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public Context() {
1515
macInstallerGenerators.add(new GeneratePkg());
1616
windowsInstallerGenerators.add(new GenerateSetup());
1717
windowsInstallerGenerators.add(new GenerateMsi());
18+
windowsInstallerGenerators.add(new GenerateMsm());
1819
}
1920

2021
// common properties

src/main/java/io/github/fvarrui/javapackager/packagers/GenerateMsi.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ public File apply(Packager packager) throws Exception {
2525
Logger.warn(getArtifactName() + " generation skipped by 'winConfig.generateMsi' property!");
2626
return null;
2727
}
28+
29+
File msmFile = new GenerateMsm().apply(windowsPackager);
30+
Logger.info("MSM file generated in " + msmFile);
2831

2932
File assetsFolder = windowsPackager.getAssetsFolder();
3033
String name = windowsPackager.getName();
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package io.github.fvarrui.javapackager.packagers;
2+
3+
import java.io.File;
4+
5+
import io.github.fvarrui.javapackager.utils.CommandUtils;
6+
import io.github.fvarrui.javapackager.utils.Logger;
7+
import io.github.fvarrui.javapackager.utils.VelocityUtils;
8+
import io.github.fvarrui.javapackager.utils.XMLUtils;
9+
10+
/**
11+
* Creates a MSI file including all app folder's content only for
12+
* Windows so app could be easily distributed
13+
*/
14+
public class GenerateMsm extends ArtifactGenerator {
15+
16+
public GenerateMsm() {
17+
super("MSI merge module");
18+
}
19+
20+
@Override
21+
public File apply(Packager packager) throws Exception {
22+
WindowsPackager windowsPackager = (WindowsPackager) packager;
23+
24+
if (windowsPackager.getMsmFile() != null) return null;
25+
26+
if (!windowsPackager.getWinConfig().isGenerateMsm() && !windowsPackager.getWinConfig().isGenerateMsi()) {
27+
Logger.warn(getArtifactName() + " generation skipped by 'winConfig.generateMsm' property!");
28+
return null;
29+
}
30+
31+
File assetsFolder = windowsPackager.getAssetsFolder();
32+
String name = windowsPackager.getName();
33+
File outputDirectory = windowsPackager.getOutputDirectory();
34+
String version = windowsPackager.getVersion();
35+
36+
// generates WXS file from velocity template
37+
File wxsFile = new File(assetsFolder, name + ".msm.wxs");
38+
VelocityUtils.render("windows/msm.wxs.vtl", wxsFile, windowsPackager);
39+
Logger.info("WXS file generated in " + wxsFile + "!");
40+
41+
// pretiffy wxs
42+
XMLUtils.prettify(wxsFile);
43+
44+
// candle wxs file
45+
Logger.info("Compiling file " + wxsFile);
46+
File wixobjFile = new File(assetsFolder, name + ".msm.wixobj");
47+
CommandUtils.execute("candle", "-out", wixobjFile, wxsFile);
48+
Logger.info("WIXOBJ file generated in " + wixobjFile + "!");
49+
50+
// lighting wxs file
51+
Logger.info("Linking file " + wixobjFile);
52+
File msmFile = new File(outputDirectory, name + "_" + version + ".msm");
53+
CommandUtils.execute("light", "-spdb", "-out", msmFile, wixobjFile);
54+
55+
// setup file
56+
if (!msmFile.exists()) {
57+
throw new Exception("MSI installer file generation failed!");
58+
}
59+
60+
windowsPackager.setMsmFile(msmFile);
61+
62+
return msmFile;
63+
}
64+
65+
}

src/main/java/io/github/fvarrui/javapackager/packagers/GenerateSetup.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public GenerateSetup() {
2121
public File apply(Packager packager) throws Exception {
2222
WindowsPackager windowsPackager = (WindowsPackager) packager;
2323

24-
if (!windowsPackager.getWinConfig().isGenerateMsi()) {
24+
if (!windowsPackager.getWinConfig().isGenerateSetup()) {
2525
Logger.warn(getArtifactName() + " generation skipped by 'winConfig.generateSetup' property!");
2626
return null;
2727
}

src/main/java/io/github/fvarrui/javapackager/packagers/WindowsPackager.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public class WindowsPackager extends Packager {
1010

1111
private String jarPath;
1212
private File manifestFile;
13+
private File msmFile;
1314

1415
public WindowsPackager() {
1516
super();
@@ -24,6 +25,14 @@ public File getManifestFile() {
2425
return manifestFile;
2526
}
2627

28+
public File getMsmFile() {
29+
return msmFile;
30+
}
31+
32+
public void setMsmFile(File msmFile) {
33+
this.msmFile = msmFile;
34+
}
35+
2736
@Override
2837
public void doInit() throws Exception {
2938

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#set ($id = 0)
2+
#macro(list $file)
3+
#set($guid = $GUID.randomUUID())
4+
#set($id = $id + 1)
5+
#if($file.isDirectory())
6+
<Directory Id="_${id}" Name="${file.name}">
7+
#foreach($child in $file.listFiles())
8+
#list($child)
9+
#end
10+
</Directory>
11+
#else
12+
<Component Id="_${id}" Guid="${guid}" Win64="yes">
13+
#if($file.equals(${info.executable}))
14+
<File Id="exeFile" Name="${file.name}" KeyPath="yes" Source="${file}">
15+
<Shortcut Id="ApplicationStartMenuShortcut" Name="${info.name}" Description="${info.description}" Directory="ProgramMenuFolder" />
16+
</File>
17+
<RemoveFolder Id="ApplicationProgramsFolder" On="uninstall" />
18+
<RegistryValue Root="HKLM" Key="Software\\${info.organizationName}\\${info.name}" Name="installed" Type="integer" Value="1" />
19+
#else
20+
<File Id="_${id}f" Name="${file.name}" KeyPath="yes" Source="${file}"/>
21+
#end
22+
</Component>
23+
#end
24+
#end
25+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
26+
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
27+
<Module Id="${info.name}_Module" Codepage="1252" Language="1033" Version="${info.winConfig.productVersion}">
28+
<Package Id="${GUID.randomUUID()}" Manufacturer="${info.organizationName}" InstallerVersion="200" Languages="1033" Platform="x64" SummaryCodepage="1252" Description="${info.description}"/>
29+
<Directory Id="TARGETDIR" Name="SourceDir">
30+
#list(${info.appFolder})
31+
<Directory Id="ProgramMenuFolder" />
32+
</Directory>
33+
</Module>
34+
</Wix>

src/main/resources/windows/wxs.vtl

Lines changed: 7 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,22 @@
1-
#macro(list $file)
2-
#set($guid = $GUID.randomUUID())
3-
#set($id = $guid.toString().replaceAll('-','_'))
4-
#if($file.isDirectory())
5-
#if($file.equals($info.appFolder))
6-
<Directory Id="INSTALLDIR" Name="${file.name}">
7-
#else
8-
<Directory Id="_${id}" Name="${file.name}">
9-
#end
10-
#foreach($child in $file.listFiles())
11-
#list($child)
12-
#end
13-
</Directory>
14-
#else
15-
#set($added = $features.add($id))
16-
<Component Id="_${id}" Guid="${guid}" Win64="yes">
17-
#if($file.equals(${info.executable}))
18-
<File Id="exeFile" Name="${file.name}" KeyPath="yes" DiskId="1" Source="${file}"/>
19-
#else
20-
<File Id="_${GUID.randomUUID().toString().replaceAll('-','_')}" Name="${file.name}" KeyPath="yes" DiskId="1" Source="${file}"/>
21-
#end
22-
</Component>
23-
#end
24-
#end
1+
#set($moduleName = $info.name + "_Module")
252
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
263
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
274
<Product Id="*" Codepage="1252" Language="1033" Manufacturer="${info.organizationName}" Name="${info.name}" UpgradeCode="${info.winConfig.msiUpgradeCode}" Version="${info.winConfig.productVersion}">
28-
<Package Compressed="yes" InstallScope="perMachine" InstallerVersion="200" Languages="1033" Platform="x64" SummaryCodepage="1252"/>
5+
<Package Compressed="yes" InstallScope="perMachine" InstallerVersion="200" Languages="1033" Platform="x64" SummaryCodepage="1252" Description="${info.description}"/>
296
<Media Id="1" Cabinet="Application.cab" EmbedCab="yes"/>
307
<Directory Id="TARGETDIR" Name="SourceDir">
318
<Directory Id="ProgramFiles64Folder">
32-
#list(${info.appFolder})
9+
<Merge Id="${moduleName}" Language="1033" SourceFile="${info.msmFile}" DiskId="1" />
3310
</Directory>
34-
<Directory Id="ProgramMenuFolder">
35-
<Directory Id="ApplicationProgramsFolder" Name="${info.name}">
36-
<Component Id="ApplicationShortcut" Guid="${GUID.randomUUID()}">
37-
<Shortcut Id="ApplicationStartMenuShortcut" Name="${info.name}" Description="${info.description}" Target="[#exeFile]" WorkingDirectory="INSTALLDIR" />
38-
<RemoveFolder Id="ApplicationProgramsFolder" On="uninstall" />
39-
<RegistryValue Root="HKCU" Key="Software\\${info.organizationName}\\${info.name}" Name="installed" Type="integer" Value="1" KeyPath="yes" />
40-
</Component>
41-
</Directory>
42-
</Directory>
4311
</Directory>
44-
<Feature Id="_${GUID.randomUUID().toString().replaceAll('-','_')}" Absent="disallow" AllowAdvertise="no" ConfigurableDirectory="INSTALLDIR" Description="${info.description}" Level="1" Title="${info.displayName}">
45-
#foreach($feature in $features)
46-
<ComponentRef Id="_${feature}"/>
47-
#end
48-
<ComponentRef Id="ApplicationShortcut"/>
12+
<Feature Id="_${GUID.randomUUID().toString().replaceAll('-','_')}" Absent="disallow" AllowAdvertise="no" ConfigurableDirectory="TARGETDIR" Description="${info.description}" Level="1" Title="${info.displayName}">
13+
<MergeRef Id="${moduleName}"/>
4914
</Feature>
5015
<Icon Id="ICONFILE" SourceFile="${info.iconFile.getAbsolutePath()}"/>
5116
<Property Id="ARPPRODUCTICON" Value="ICONFILE"/>
52-
#if($info.licenseFile)
17+
#if($info.licenseFile)
5318
<WixVariable Id="WixUILicenseRtf" Value="LICENSE"/>
5419
#end
55-
<MajorUpgrade AllowDowngrades="no" AllowSameVersionUpgrades="yes" DowngradeErrorMessage="A later version of ${info.winConfig.productName} is already installed. Setup will now exit." IgnoreRemoveFailure="no"/>
20+
<MajorUpgrade AllowDowngrades="no" AllowSameVersionUpgrades="no" DowngradeErrorMessage="A later version of ${info.winConfig.productName} is already installed. Setup will now exit." IgnoreRemoveFailure="no"/>
5621
</Product>
5722
</Wix>

0 commit comments

Comments
 (0)