< prev index next >

src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java

Print this page




 575 
 576         data.put("REGISTRY_ROOT", getRegistryRoot(params));
 577 
 578         boolean canUseWix36Features = CAN_USE_WIX36.fetchFrom(params);
 579         data.put("WIX36_ONLY_START",
 580                 canUseWix36Features ? "" : "<!--");
 581         data.put("WIX36_ONLY_END",
 582                 canUseWix36Features ? "" : "-->");
 583 
 584         if (MSI_SYSTEM_WIDE.fetchFrom(params)) {
 585             data.put("INSTALL_SCOPE", "perMachine");
 586         } else {
 587             data.put("INSTALL_SCOPE", "perUser");
 588         }
 589 
 590         data.put("PLATFORM", "x64");
 591         data.put("WIN64", "yes");
 592 
 593         data.put("UI_BLOCK", getUIBlock(params));
 594 









 595         List<Map<String, ? super Object>> secondaryLaunchers =
 596                 SECONDARY_LAUNCHERS.fetchFrom(params);
 597 
 598         StringBuilder secondaryLauncherIcons = new StringBuilder();
 599         for (int i = 0; i < secondaryLaunchers.size(); i++) {
 600             Map<String, ? super Object> sl = secondaryLaunchers.get(i);
 601             // <Icon Id="DesktopIcon.exe" SourceFile="APPLICATION_ICON" />
 602             if (SHORTCUT_HINT.fetchFrom(sl) || MENU_HINT.fetchFrom(sl)) {
 603                 File secondaryLauncher = new File(imageRootDir,
 604                         WinAppBundler.getLauncherName(sl));
 605                 String secondaryLauncherPath =
 606                         relativePath(imageRootDir, secondaryLauncher);
 607                 String secondaryLauncherIconPath =
 608                         secondaryLauncherPath.replace(".exe", ".ico");
 609 
 610                 secondaryLauncherIcons.append("        <Icon Id=\"Launcher");
 611                 secondaryLauncherIcons.append(i);
 612                 secondaryLauncherIcons.append(".exe\" SourceFile=\"");
 613                 secondaryLauncherIcons.append(secondaryLauncherIconPath);
 614                 secondaryLauncherIcons.append("\" />\r\n");


 618 
 619         String wxs = RUNTIME_INSTALLER.fetchFrom(params) ?
 620                 MSI_PROJECT_TEMPLATE_SERVER_JRE : MSI_PROJECT_TEMPLATE;
 621 
 622         Writer w = new BufferedWriter(
 623                 new FileWriter(getConfig_ProjectFile(params)));
 624 
 625         String content = preprocessTextResource(
 626                 getConfig_ProjectFile(params).getName(),
 627                 I18N.getString("resource.wix-config-file"),
 628                 wxs, data, VERBOSE.fetchFrom(params),
 629                 RESOURCE_DIR.fetchFrom(params));
 630         w.write(content);
 631         w.close();
 632         return true;
 633     }
 634     private int id;
 635     private int compId;
 636     private final static String LAUNCHER_ID = "LauncherId";
 637 






















 638     /**
 639      * Overrides the dialog sequence in built-in dialog set "WixUI_InstallDir"
 640      * to exclude license dialog
 641      */
 642     private static final String TWEAK_FOR_EXCLUDING_LICENSE =
 643               "     <Publish Dialog=\"WelcomeDlg\" Control=\"Next\""
 644             + "              Event=\"NewDialog\" Value=\"InstallDirDlg\""
 645             + " Order=\"2\"> 1"
 646             + "     </Publish>\n"
 647             + "     <Publish Dialog=\"InstallDirDlg\" Control=\"Back\""
 648             + "              Event=\"NewDialog\" Value=\"WelcomeDlg\""
 649             + " Order=\"2\"> 1"
 650             + "     </Publish>\n";










 651 
 652     // Required upgrade element for installers which support major upgrade (when user
 653     // specifies --win-upgrade-uuid). We will allow downgrades.
 654     private static final String UPGRADE_BLOCK =
 655             "<MajorUpgrade AllowDowngrades=\"yes\"/>";
 656 
 657     private String getUpgradeBlock(Map<String, ? super Object> params) {
 658         if (UPGRADE_UUID.getIsDefaultValue()) {
 659             return "";
 660         } else {
 661             return UPGRADE_BLOCK;
 662         }
 663     }
 664 
 665     /**
 666      * Creates UI element using WiX built-in dialog sets
 667      *     - WixUI_InstallDir/WixUI_Minimal.
 668      * The dialog sets are the closest to what we want to implement.
 669      *
 670      * WixUI_Minimal for license dialog only
 671      * WixUI_InstallDir for installdir dialog only or for both
 672      * installdir/license dialogs
 673      */
 674     private String getUIBlock(Map<String, ? super Object> params) {
 675         String uiBlock = "     <UI/>\n"; // UI-less element








 676 
 677         if (INSTALLDIR_CHOOSER.fetchFrom(params)) {
 678             boolean enableTweakForExcludingLicense =
 679                     (getLicenseFile(params) == null);
 680             uiBlock = "     <UI>\n"
 681                     + "     <Property Id=\"WIXUI_INSTALLDIR\""
 682                     + " Value=\"APPLICATIONFOLDER\" />\n"
 683                     + "     <UIRef Id=\"WixUI_InstallDir\" />\n"
 684                     + (enableTweakForExcludingLicense ?
 685                             TWEAK_FOR_EXCLUDING_LICENSE : "")
 686                     +"     </UI>\n";
 687         } else if (getLicenseFile(params) != null) {
 688             uiBlock = "     <UI>\n"
 689                     + "     <UIRef Id=\"WixUI_Minimal\" />\n"
 690                     + "     </UI>\n";
 691         }
 692 
 693         return uiBlock;
 694     }
 695 
 696     private void walkFileTree(Map<String, ? super Object> params,
 697             File root, PrintStream out, String prefix) {
 698         List<File> dirs = new ArrayList<>();
 699         List<File> files = new ArrayList<>();
 700 
 701         if (!root.isDirectory()) {
 702             throw new RuntimeException(
 703                     MessageFormat.format(
 704                             I18N.getString("error.cannot-walk-directory"),
 705                             root.getAbsolutePath()));
 706         }
 707 
 708         // sort to files and dirs
 709         File[] children = root.listFiles();
 710         if (children != null) {


1059         boolean enableLicenseUI = (getLicenseFile(params) != null);
1060         boolean enableInstalldirUI = INSTALLDIR_CHOOSER.fetchFrom(params);
1061 
1062         List<String> commandLine = new ArrayList<>();
1063 
1064         commandLine.add(TOOL_LIGHT_EXECUTABLE.fetchFrom(params));
1065         if (enableLicenseUI) {
1066             commandLine.add("-dWixUILicenseRtf="+getLicenseFile(params));
1067         }
1068         commandLine.add("-nologo");
1069         commandLine.add("-spdb");
1070         commandLine.add("-sice:60");
1071                 // ignore warnings due to "missing launcguage info" (ICE60)
1072         commandLine.add(candleOut.getAbsolutePath());
1073         commandLine.add("-ext");
1074         commandLine.add("WixUtilExtension");
1075         if (enableLicenseUI || enableInstalldirUI) {
1076             commandLine.add("-ext");
1077             commandLine.add("WixUIExtension.dll");
1078         }







1079         commandLine.add("-out");
1080         commandLine.add(msiOut.getAbsolutePath());
1081 
1082         // create .msi
1083         pb = new ProcessBuilder(commandLine);
1084 
1085         pb = pb.directory(WIN_APP_IMAGE.fetchFrom(params));
1086         IOUtils.exec(pb, false);
1087 
1088         candleOut.delete();
1089         IOUtils.deleteRecursive(tmpDir);
1090 
1091         return msiOut;
1092     }
1093 
1094     public static void ensureByMutationFileIsRTF(File f) {
1095         if (f == null || !f.isFile()) return;
1096 
1097         try {
1098             boolean existingLicenseIsRTF = false;




 575 
 576         data.put("REGISTRY_ROOT", getRegistryRoot(params));
 577 
 578         boolean canUseWix36Features = CAN_USE_WIX36.fetchFrom(params);
 579         data.put("WIX36_ONLY_START",
 580                 canUseWix36Features ? "" : "<!--");
 581         data.put("WIX36_ONLY_END",
 582                 canUseWix36Features ? "" : "-->");
 583 
 584         if (MSI_SYSTEM_WIDE.fetchFrom(params)) {
 585             data.put("INSTALL_SCOPE", "perMachine");
 586         } else {
 587             data.put("INSTALL_SCOPE", "perUser");
 588         }
 589 
 590         data.put("PLATFORM", "x64");
 591         data.put("WIN64", "yes");
 592 
 593         data.put("UI_BLOCK", getUIBlock(params));
 594 
 595         // Add CA to check install dir
 596         if (INSTALLDIR_CHOOSER.fetchFrom(params)) {
 597             data.put("CA_BLOCK", CA_BLOCK);
 598             data.put("INVALID_INSTALL_DIR_DLG_BLOCK", INVALID_INSTALL_DIR_DLG_BLOCK);
 599         } else {
 600             data.put("CA_BLOCK", "");
 601             data.put("INVALID_INSTALL_DIR_DLG_BLOCK", "");
 602         }
 603 
 604         List<Map<String, ? super Object>> secondaryLaunchers =
 605                 SECONDARY_LAUNCHERS.fetchFrom(params);
 606 
 607         StringBuilder secondaryLauncherIcons = new StringBuilder();
 608         for (int i = 0; i < secondaryLaunchers.size(); i++) {
 609             Map<String, ? super Object> sl = secondaryLaunchers.get(i);
 610             // <Icon Id="DesktopIcon.exe" SourceFile="APPLICATION_ICON" />
 611             if (SHORTCUT_HINT.fetchFrom(sl) || MENU_HINT.fetchFrom(sl)) {
 612                 File secondaryLauncher = new File(imageRootDir,
 613                         WinAppBundler.getLauncherName(sl));
 614                 String secondaryLauncherPath =
 615                         relativePath(imageRootDir, secondaryLauncher);
 616                 String secondaryLauncherIconPath =
 617                         secondaryLauncherPath.replace(".exe", ".ico");
 618 
 619                 secondaryLauncherIcons.append("        <Icon Id=\"Launcher");
 620                 secondaryLauncherIcons.append(i);
 621                 secondaryLauncherIcons.append(".exe\" SourceFile=\"");
 622                 secondaryLauncherIcons.append(secondaryLauncherIconPath);
 623                 secondaryLauncherIcons.append("\" />\r\n");


 627 
 628         String wxs = RUNTIME_INSTALLER.fetchFrom(params) ?
 629                 MSI_PROJECT_TEMPLATE_SERVER_JRE : MSI_PROJECT_TEMPLATE;
 630 
 631         Writer w = new BufferedWriter(
 632                 new FileWriter(getConfig_ProjectFile(params)));
 633 
 634         String content = preprocessTextResource(
 635                 getConfig_ProjectFile(params).getName(),
 636                 I18N.getString("resource.wix-config-file"),
 637                 wxs, data, VERBOSE.fetchFrom(params),
 638                 RESOURCE_DIR.fetchFrom(params));
 639         w.write(content);
 640         w.close();
 641         return true;
 642     }
 643     private int id;
 644     private int compId;
 645     private final static String LAUNCHER_ID = "LauncherId";
 646 
 647     private static final String CA_BLOCK =
 648             "<Binary Id=\"CustomActionDLL\" SourceFile=\"wixhelper.dll\" />\n" +
 649             "<CustomAction Id=\"CHECK_INSTALLDIR\" BinaryKey=\"CustomActionDLL\" " +
 650             "DllEntry=\"CheckInstallDir\" />";
 651 
 652     private static final String INVALID_INSTALL_DIR_DLG_BLOCK =
 653             "<Dialog Id=\"InvalidInstallDir\" Width=\"300\" Height=\"85\" " +
 654             "Title=\"[ProductName] Setup\" NoMinimize=\"yes\">\n" +
 655             "<Control Id=\"InvalidInstallDirYes\" Type=\"PushButton\" X=\"100\" Y=\"55\" " +
 656             "Width=\"50\" Height=\"15\" Default=\"no\" Cancel=\"no\" Text=\"Yes\">\n" +
 657             "<Publish Event=\"NewDialog\" Value=\"VerifyReadyDlg\">1</Publish>\n" +
 658             "</Control>\n" +
 659             "<Control Id=\"InvalidInstallDirNo\" Type=\"PushButton\" X=\"150\" Y=\"55\" " +
 660             "Width=\"50\" Height=\"15\" Default=\"yes\" Cancel=\"yes\" Text=\"No\">\n" +
 661             "<Publish Event=\"NewDialog\" Value=\"InstallDirDlg\">1</Publish>\n" +
 662             "</Control>\n" +
 663             "<Control Id=\"Text\" Type=\"Text\" X=\"25\" Y=\"15\" Width=\"250\" Height=\"30\" " +
 664             "TabSkip=\"no\">\n" +
 665             "<Text>" + I18N.getString("message.install.dir.exist") + "</Text>\n" +
 666             "</Control>\n" +
 667             "</Dialog>";
 668 
 669     /**
 670      * Overrides the dialog sequence in built-in dialog set "WixUI_InstallDir"
 671      * to exclude license dialog
 672      */
 673     private static final String TWEAK_FOR_EXCLUDING_LICENSE =
 674               "     <Publish Dialog=\"WelcomeDlg\" Control=\"Next\""
 675             + "              Event=\"NewDialog\" Value=\"InstallDirDlg\""
 676             + " Order=\"2\">1</Publish>\n"

 677             + "     <Publish Dialog=\"InstallDirDlg\" Control=\"Back\""
 678             + "              Event=\"NewDialog\" Value=\"WelcomeDlg\""
 679             + " Order=\"2\">1</Publish>\n";
 680 
 681     private static final String CHECK_INSTALL_DLG_CTRL =
 682               "     <Publish Dialog=\"InstallDirDlg\" Control=\"Next\""
 683             + "              Event=\"DoAction\" Value=\"CHECK_INSTALLDIR\""
 684             + " Order=\"3\">1</Publish>\n"
 685             + "     <Publish Dialog=\"InstallDirDlg\" Control=\"Next\""
 686             + "              Event=\"NewDialog\" Value=\"InvalidInstallDir\""
 687             + " Order=\"5\">INSTALLDIR_VALID=\"0\"</Publish>\n"
 688             + "     <Publish Dialog=\"InstallDirDlg\" Control=\"Next\""
 689             + "              Event=\"NewDialog\" Value=\"VerifyReadyDlg\""
 690             + " Order=\"5\">INSTALLDIR_VALID=\"1\"</Publish>\n";
 691 
 692     // Required upgrade element for installers which support major upgrade (when user
 693     // specifies --win-upgrade-uuid). We will allow downgrades.
 694     private static final String UPGRADE_BLOCK =
 695             "<MajorUpgrade AllowDowngrades=\"yes\"/>";
 696 
 697     private String getUpgradeBlock(Map<String, ? super Object> params) {
 698         if (UPGRADE_UUID.getIsDefaultValue()) {
 699             return "";
 700         } else {
 701             return UPGRADE_BLOCK;
 702         }
 703     }
 704 
 705     /**
 706      * Creates UI element using WiX built-in dialog sets
 707      *     - WixUI_InstallDir/WixUI_Minimal.
 708      * The dialog sets are the closest to what we want to implement.
 709      *
 710      * WixUI_Minimal for license dialog only
 711      * WixUI_InstallDir for installdir dialog only or for both
 712      * installdir/license dialogs
 713      */
 714     private String getUIBlock(Map<String, ? super Object> params) throws IOException {
 715         String uiBlock = ""; // UI-less element
 716 
 717         // Copy CA dll to include with installer
 718         if (INSTALLDIR_CHOOSER.fetchFrom(params)) {
 719             File helper = new File(CONFIG_ROOT.fetchFrom(params), "wixhelper.dll");
 720             try (InputStream is_lib = getResourceAsStream("wixhelper.dll")) {
 721                 Files.copy(is_lib, helper.toPath());
 722             }
 723         }
 724 
 725         if (INSTALLDIR_CHOOSER.fetchFrom(params)) {
 726             boolean enableTweakForExcludingLicense =
 727                     (getLicenseFile(params) == null);
 728             uiBlock = "     <Property Id=\"WIXUI_INSTALLDIR\""

 729                     + " Value=\"APPLICATIONFOLDER\" />\n"
 730                     + "     <UIRef Id=\"WixUI_InstallDir\" />\n"
 731                     + (enableTweakForExcludingLicense ?
 732                             TWEAK_FOR_EXCLUDING_LICENSE : "")
 733                     + CHECK_INSTALL_DLG_CTRL;
 734         } else if (getLicenseFile(params) != null) {
 735             uiBlock = "     <UIRef Id=\"WixUI_Minimal\" />\n";


 736         }
 737 
 738         return uiBlock;
 739     }
 740 
 741     private void walkFileTree(Map<String, ? super Object> params,
 742             File root, PrintStream out, String prefix) {
 743         List<File> dirs = new ArrayList<>();
 744         List<File> files = new ArrayList<>();
 745 
 746         if (!root.isDirectory()) {
 747             throw new RuntimeException(
 748                     MessageFormat.format(
 749                             I18N.getString("error.cannot-walk-directory"),
 750                             root.getAbsolutePath()));
 751         }
 752 
 753         // sort to files and dirs
 754         File[] children = root.listFiles();
 755         if (children != null) {


1104         boolean enableLicenseUI = (getLicenseFile(params) != null);
1105         boolean enableInstalldirUI = INSTALLDIR_CHOOSER.fetchFrom(params);
1106 
1107         List<String> commandLine = new ArrayList<>();
1108 
1109         commandLine.add(TOOL_LIGHT_EXECUTABLE.fetchFrom(params));
1110         if (enableLicenseUI) {
1111             commandLine.add("-dWixUILicenseRtf="+getLicenseFile(params));
1112         }
1113         commandLine.add("-nologo");
1114         commandLine.add("-spdb");
1115         commandLine.add("-sice:60");
1116                 // ignore warnings due to "missing launcguage info" (ICE60)
1117         commandLine.add(candleOut.getAbsolutePath());
1118         commandLine.add("-ext");
1119         commandLine.add("WixUtilExtension");
1120         if (enableLicenseUI || enableInstalldirUI) {
1121             commandLine.add("-ext");
1122             commandLine.add("WixUIExtension.dll");
1123         }
1124 
1125         // Only needed if we using CA dll, so Wix can find it
1126         if (enableInstalldirUI) {
1127             commandLine.add("-b");
1128             commandLine.add(CONFIG_ROOT.fetchFrom(params).getAbsolutePath());
1129         }
1130 
1131         commandLine.add("-out");
1132         commandLine.add(msiOut.getAbsolutePath());
1133 
1134         // create .msi
1135         pb = new ProcessBuilder(commandLine);
1136 
1137         pb = pb.directory(WIN_APP_IMAGE.fetchFrom(params));
1138         IOUtils.exec(pb, false);
1139 
1140         candleOut.delete();
1141         IOUtils.deleteRecursive(tmpDir);
1142 
1143         return msiOut;
1144     }
1145 
1146     public static void ensureByMutationFileIsRTF(File f) {
1147         if (f == null || !f.isFile()) return;
1148 
1149         try {
1150             boolean existingLicenseIsRTF = false;


< prev index next >