# HG changeset patch # User herrick # Date 1572897961 18000 # Node ID fbaf2e6402ad1a18cbd2e8f10b0d61740011235c # Parent d92acb18e3007eefebff715d7d38c84afcd92ab0 8232919 : If user installs msi and exe, two installations are found in Add/Remove Submitted-by: asemenyuk Reviewed-by: aherrick, almatvee diff -r d92acb18e300 -r fbaf2e6402ad make/CompileJavaModules.gmk --- a/make/CompileJavaModules.gmk Mon Nov 04 14:57:27 2019 -0500 +++ b/make/CompileJavaModules.gmk Mon Nov 04 15:06:01 2019 -0500 @@ -381,7 +381,7 @@ ################################################################################ jdk.jpackage_COPY += .gif .png .txt .spec .script .prerm .preinst .postrm .postinst .list .sh \ - .desktop .copyright .control .plist .template .icns .scpt .entitlements .wxs .wxl .ico .bmp + .desktop .copyright .control .plist .template .icns .scpt .entitlements .wxs .wxl .wxi .ico .bmp jdk.jpackage_CLEAN += .properties diff -r d92acb18e300 -r fbaf2e6402ad src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinAppBundler.java --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinAppBundler.java Mon Nov 04 14:57:27 2019 -0500 +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinAppBundler.java Mon Nov 04 15:06:01 2019 -0500 @@ -31,7 +31,6 @@ import java.util.*; import static jdk.jpackage.internal.WindowsBundlerParam.*; -import static jdk.jpackage.internal.WinMsiBundler.WIN_APP_IMAGE; public class WinAppBundler extends AbstractImageBundler { diff -r d92acb18e300 -r fbaf2e6402ad src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java Mon Nov 04 14:57:27 2019 -0500 +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java Mon Nov 04 15:06:01 2019 -0500 @@ -27,6 +27,7 @@ import java.io.*; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -34,6 +35,7 @@ import java.util.*; import java.util.regex.Pattern; import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; @@ -135,12 +137,12 @@ (s, p) -> s ); - public static final BundlerParamInfo UPGRADE_UUID = + private static final BundlerParamInfo UPGRADE_UUID = new WindowsBundlerParam<>( Arguments.CLIOptions.WIN_UPGRADE_UUID.getId(), - UUID.class, - params -> UUID.randomUUID(), - (s, p) -> UUID.fromString(s)); + String.class, + null, + (s, p) -> s); @Override public String getName() { @@ -186,6 +188,27 @@ return false; } + private static UUID getUpgradeCode(Map params) { + String upgradeCode = UPGRADE_UUID.fetchFrom(params); + if (upgradeCode != null) { + return UUID.fromString(upgradeCode); + } + return createNameUUID("UpgradeCode", params, List.of(VENDOR, APP_NAME)); + } + + private static UUID getProductCode(Map params) { + return createNameUUID("ProductCode", params, List.of(VENDOR, APP_NAME, + VERSION)); + } + + private static UUID createNameUUID(String prefix, + Map params, + List> components) { + String key = Stream.concat(Stream.of(prefix), components.stream().map( + c -> c.fetchFrom(params))).collect(Collectors.joining("/")); + return UUID.nameUUIDFromBytes(key.getBytes(StandardCharsets.UTF_8)); + } + @Override public boolean validate(Map params) throws ConfigException { @@ -194,6 +217,12 @@ wixToolset = WixTool.toolset(); } + try { + getUpgradeCode(params); + } catch (IllegalArgumentException ex) { + throw new ConfigException(ex); + } + for (var toolInfo: wixToolset.values()) { Log.verbose(MessageFormat.format(I18N.getString( "message.tool-version"), toolInfo.path.getFileName(), @@ -225,10 +254,8 @@ List mimes = FA_CONTENT_TYPE.fetchFrom(assoc); if (mimes.size() > 1) { throw new ConfigException(MessageFormat.format( - I18N.getString("error.too-many-content-" - + "types-for-file-association"), i), - I18N.getString("error.too-many-content-" - + "types-for-file-association.advice")); + I18N.getString("error.too-many-content-types-for-file-association"), i), + I18N.getString("error.too-many-content-types-for-file-association.advice")); } } } @@ -362,32 +389,27 @@ Map params) throws IOException { Map data = new HashMap<>(); - UUID productGUID = UUID.randomUUID(); + final UUID productCode = getProductCode(params); + final UUID upgradeCode = getUpgradeCode(params); - Log.verbose(MessageFormat.format( - I18N.getString("message.generated-product-guid"), - productGUID.toString())); + data.put("JpProductCode", productCode.toString()); + data.put("JpProductUpgradeCode", upgradeCode.toString()); - // we use random GUID for product itself but - // user provided for upgrade guid - // Upgrade guid is important to decide whether it is an upgrade of - // installed app. I.e. we need it to be the same for - // 2 different versions of app if possible - data.put("JpProductCode", productGUID.toString()); - data.put("JpProductUpgradeCode", - UPGRADE_UUID.fetchFrom(params).toString()); + Log.verbose(MessageFormat.format(I18N.getString("message.product-code"), + productCode)); + Log.verbose(MessageFormat.format(I18N.getString("message.upgrade-code"), + upgradeCode)); - if (!UPGRADE_UUID.getIsDefaultValue()) { - data.put("JpAllowDowngrades", "yes"); - } + data.put("JpAllowUpgrades", "yes"); data.put("JpAppName", APP_NAME.fetchFrom(params)); data.put("JpAppDescription", DESCRIPTION.fetchFrom(params)); data.put("JpAppVendor", VENDOR.fetchFrom(params)); data.put("JpAppVersion", PRODUCT_VERSION.fetchFrom(params)); - data.put("JpConfigDir", - CONFIG_ROOT.fetchFrom(params).getAbsolutePath()); + final Path configDir = CONFIG_ROOT.fetchFrom(params).toPath(); + + data.put("JpConfigDir", configDir.toAbsolutePath().toString()); if (MSI_SYSTEM_WIDE.fetchFrom(params)) { data.put("JpIsSystemWide", "yes"); @@ -422,18 +444,16 @@ } createResource("main.wxs", params) - .setCategory(I18N.getString("resource.wxs-file")) - .saveToFile(Paths.get(getConfig_ProjectFile(params) - .getAbsolutePath())); + .setCategory(I18N.getString("resource.main-wix-file")) + .saveToFile(configDir.resolve("main.wxs")); + createResource("overrides.wxi", params) + .setCategory(I18N.getString("resource.overrides-wix-file")) + .saveToFile(configDir.resolve("overrides.wxi")); return data; } - private File getConfig_ProjectFile(Map params) { - return new File(CONFIG_ROOT.fetchFrom(params), "main.wxs"); - } - private File buildMSI(Map params, Map wixVars, File outdir) throws IOException { diff -r d92acb18e300 -r fbaf2e6402ad src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/MsiInstallerStrings_en.wxl --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/MsiInstallerStrings_en.wxl Mon Nov 04 14:57:27 2019 -0500 +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/MsiInstallerStrings_en.wxl Mon Nov 04 15:06:01 2019 -0500 @@ -1,4 +1,7 @@ The folder [INSTALLDIR] already exist. Would you like to install to that folder anyway? + Main Feature + A higher version of [ProductName] is already installed. Downgrades disabled. Setup will now exit. + A lower version of [ProductName] is already installed. Upgrades disabled. Setup will now exit. diff -r d92acb18e300 -r fbaf2e6402ad src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/MsiInstallerStrings_ja.wxl --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/MsiInstallerStrings_ja.wxl Mon Nov 04 14:57:27 2019 -0500 +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/MsiInstallerStrings_ja.wxl Mon Nov 04 15:06:01 2019 -0500 @@ -1,4 +1,7 @@ - + The folder [INSTALLDIR] already exist. Would you like to install to that folder anyway? + Main Feature + A higher version of [ProductName] is already installed. Downgrades disabled. Setup will now exit. + A lower version of [ProductName] is already installed. Upgrades disabled. Setup will now exit. diff -r d92acb18e300 -r fbaf2e6402ad src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/MsiInstallerStrings_zh_CN.wxl --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/MsiInstallerStrings_zh_CN.wxl Mon Nov 04 14:57:27 2019 -0500 +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/MsiInstallerStrings_zh_CN.wxl Mon Nov 04 15:06:01 2019 -0500 @@ -1,4 +1,7 @@ - + The folder [INSTALLDIR] already exist. Would you like to install to that folder anyway? + Main Feature + A higher version of [ProductName] is already installed. Downgrades disabled. Setup will now exit. + A lower version of [ProductName] is already installed. Upgrades disabled. Setup will now exit. diff -r d92acb18e300 -r fbaf2e6402ad src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources.properties --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources.properties Mon Nov 04 14:57:27 2019 -0500 +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources.properties Mon Nov 04 15:06:01 2019 -0500 @@ -35,7 +35,8 @@ resource.post-app-image-script=script to run after application image is populated resource.post-msi-script=script to run after msi file for exe installer is created resource.wxl-file-name=MsiInstallerStrings_en.wxl -resource.wxs-file=Main wxs project file +resource.main-wix-file=Main WiX project file +resource.overrides-wix-file=Overrides WiX project file error.no-wix-tools=Can not find WiX tools (light.exe, candle.exe) error.no-wix-tools.advice=Download WiX 3.0 or later from https://wixtoolset.org and add it to the PATH. @@ -58,7 +59,8 @@ message.wrong-tool-version=Detected [{0}] version {1} but version {2} is required. message.version-string-too-many-components=Version sting may have up to 3 components - major.minor.build . message.use-wix36-features=WiX {0} detected. Enabling advanced cleanup action. -message.generated-product-guid=Generated product GUID: {0}. +message.product-code=MSI ProductCode: {0}. +message.upgrade-code=MSI UpgradeCode: {0}. message.preparing-msi-config=Preparing MSI config: {0}. message.generating-msi=Generating MSI: {0}. message.invalid.install.dir=Warning: Invalid install directory {0}. Install directory should be a relative sub-path under the default installation location such as "Program Files". Defaulting to application name "{1}". diff -r d92acb18e300 -r fbaf2e6402ad src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_ja.properties --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_ja.properties Mon Nov 04 14:57:27 2019 -0500 +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_ja.properties Mon Nov 04 15:06:01 2019 -0500 @@ -35,7 +35,8 @@ resource.post-app-image-script=script to run after application image is populated resource.post-msi-script=script to run after msi file for exe installer is created resource.wxl-file-name=MsiInstallerStrings_en.wxl -resource.wxs-file=Main wxs project file +resource.main-wix-file=Main WiX project file +resource.overrides-wix-file=Overrides WiX project file error.no-wix-tools=Can not find WiX tools (light.exe, candle.exe) error.no-wix-tools.advice=Download WiX 3.0 or later from https://wixtoolset.org and add it to the PATH. @@ -58,7 +59,8 @@ message.wrong-tool-version=Detected [{0}] version {1} but version {2} is required. message.version-string-too-many-components=Version sting may have up to 3 components - major.minor.build . message.use-wix36-features=WiX {0} detected. Enabling advanced cleanup action. -message.generated-product-guid=Generated product GUID: {0}. +message.product-code=MSI ProductCode: {0}. +message.upgrade-code=MSI UpgradeCode: {0}. message.preparing-msi-config=Preparing MSI config: {0}. message.generating-msi=Generating MSI: {0}. message.invalid.install.dir=Warning: Invalid install directory {0}. Install directory should be a relative sub-path under the default installation location such as "Program Files". Defaulting to application name "{1}". diff -r d92acb18e300 -r fbaf2e6402ad src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_zh_CN.properties --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_zh_CN.properties Mon Nov 04 14:57:27 2019 -0500 +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_zh_CN.properties Mon Nov 04 15:06:01 2019 -0500 @@ -35,7 +35,8 @@ resource.post-app-image-script=script to run after application image is populated resource.post-msi-script=script to run after msi file for exe installer is created resource.wxl-file-name=MsiInstallerStrings_en.wxl -resource.wxs-file=Main wxs project file +resource.main-wix-file=Main WiX project file +resource.overrides-wix-file=Overrides WiX project file error.no-wix-tools=Can not find WiX tools (light.exe, candle.exe) error.no-wix-tools.advice=Download WiX 3.0 or later from https://wixtoolset.org and add it to the PATH. @@ -58,7 +59,8 @@ message.wrong-tool-version=Detected [{0}] version {1} but version {2} is required. message.version-string-too-many-components=Version sting may have up to 3 components - major.minor.build . message.use-wix36-features=WiX {0} detected. Enabling advanced cleanup action. -message.generated-product-guid=Generated product GUID: {0}. +message.product-code=MSI ProductCode: {0}. +message.upgrade-code=MSI UpgradeCode: {0}. message.preparing-msi-config=Preparing MSI config: {0}. message.generating-msi=Generating MSI: {0}. message.invalid.install.dir=Warning: Invalid install directory {0}. Install directory should be a relative sub-path under the default installation location such as "Program Files". Defaulting to application name "{1}". diff -r d92acb18e300 -r fbaf2e6402ad src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/main.wxs --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/main.wxs Mon Nov 04 14:57:27 2019 -0500 +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/main.wxs Mon Nov 04 15:06:01 2019 -0500 @@ -8,24 +8,74 @@ - - - + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + - + diff -r d92acb18e300 -r fbaf2e6402ad src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/overrides.wxi --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/overrides.wxi Mon Nov 04 15:06:01 2019 -0500 @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff -r d92acb18e300 -r fbaf2e6402ad test/jdk/tools/jpackage/windows/WinResourceTest.java --- a/test/jdk/tools/jpackage/windows/WinResourceTest.java Mon Nov 04 14:57:27 2019 -0500 +++ b/test/jdk/tools/jpackage/windows/WinResourceTest.java Mon Nov 04 15:06:01 2019 -0500 @@ -27,6 +27,7 @@ import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; import jdk.jpackage.test.Annotations.Test; +import jdk.jpackage.test.Annotations.Parameters; import java.util.List; /** @@ -48,8 +49,22 @@ */ public class WinResourceTest { + + public WinResourceTest(String wixSource, String expectedLogMessage) { + this.wixSource = wixSource; + this.expectedLogMessage = expectedLogMessage; + } + + @Parameters + public static List data() { + return List.of(new Object[][]{ + {"main.wxs", "Using custom package resource [Main WiX project file]"}, + {"overrides.wxi", "Using custom package resource [Overrides WiX project file]"}, + }); + } + @Test - public static void test() throws IOException { + public void test() throws IOException { new PackageTest() .forTypes(PackageType.WINDOWS) .configureHelloApp() @@ -61,14 +76,14 @@ cmd.setFakeRuntime().saveConsoleOutput(true); cmd.addArguments("--resource-dir", resourceDir); - // Create invalid main wxs file in a resource dir. - TKit.createTextFile(resourceDir.resolve("main.wxs"), List.of( - "any string that is an invalid wxs file")); + // Create invalid WiX source file in a resource dir. + TKit.createTextFile(resourceDir.resolve(wixSource), List.of( + "any string that is an invalid WiX source file")); }) .addBundleVerifier((cmd, result) -> { // Assert jpackage picked custom main.wxs and failed as expected by // examining its output - TKit.assertTextStream("Using custom package resource [Main wxs project file]") + TKit.assertTextStream(expectedLogMessage) .predicate(String::startsWith) .apply(result.getOutput().stream()); TKit.assertTextStream("error CNDL0104 : Not a valid source file") @@ -77,4 +92,7 @@ .setExpectedExitCode(1) .run(); } + + final String wixSource; + final String expectedLogMessage; }