< prev index next >

src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgBundler.java

Print this page




  77         } catch (IOException ex) {
  78             Log.verbose(ex);
  79             throw new PackagerException(ex);
  80         }
  81     }
  82 
  83     private static final String hdiutil = "/usr/bin/hdiutil";
  84 
  85     private void prepareDMGSetupScript(String volumeName,
  86             Map<String, ? super Object> params) throws IOException {
  87         File dmgSetup = getConfig_VolumeScript(params);
  88         Log.verbose(MessageFormat.format(
  89                 I18N.getString("message.preparing-dmg-setup"),
  90                 dmgSetup.getAbsolutePath()));
  91 
  92         //prepare config for exe
  93         Map<String, String> data = new HashMap<>();
  94         data.put("DEPLOY_ACTUAL_VOLUME_NAME", volumeName);
  95         data.put("DEPLOY_APPLICATION_NAME", APP_NAME.fetchFrom(params));
  96 
  97         data.put("DEPLOY_INSTALL_LOCATION", "(path to desktop folder)");
  98         data.put("DEPLOY_INSTALL_NAME", "Desktop");
  99 
 100         try (Writer w = Files.newBufferedWriter(dmgSetup.toPath())) {
 101             w.write(preprocessTextResource(dmgSetup.getName(),
 102                     I18N.getString("resource.dmg-setup-script"),
 103                     DEFAULT_DMG_SETUP_SCRIPT, data, VERBOSE.fetchFrom(params),
 104                     RESOURCE_DIR.fetchFrom(params)));
 105         }
 106     }
 107 
 108     private File getConfig_VolumeScript(Map<String, ? super Object> params) {
 109         return new File(CONFIG_ROOT.fetchFrom(params),
 110                 APP_NAME.fetchFrom(params) + "-dmg-setup.scpt");
 111     }
 112 
 113     private File getConfig_VolumeBackground(
 114             Map<String, ? super Object> params) {
 115         return new File(CONFIG_ROOT.fetchFrom(params),
 116                 APP_NAME.fetchFrom(params) + "-background.png");
 117     }
 118 


 302                 hdiUtilVerbosityFlag,
 303                 "-srcfolder", srcFolder.getAbsolutePath(),
 304                 "-volname", APP_NAME.fetchFrom(params),
 305                 "-ov", protoDMG.getAbsolutePath(),
 306                 "-fs", "HFS+",
 307                 "-format", "UDRW");
 308         IOUtils.exec(pb);
 309 
 310         // mount temp image
 311         pb = new ProcessBuilder(
 312                 hdiutil,
 313                 "attach",
 314                 protoDMG.getAbsolutePath(),
 315                 hdiUtilVerbosityFlag,
 316                 "-mountroot", imagesRoot.getAbsolutePath());
 317         IOUtils.exec(pb);
 318 
 319         File mountedRoot = new File(imagesRoot.getAbsolutePath(),
 320                 APP_NAME.fetchFrom(params));
 321 

 322         // volume icon
 323         File volumeIconFile = new File(mountedRoot, ".VolumeIcon.icns");
 324         IOUtils.copyFile(getConfig_VolumeIcon(params),
 325                 volumeIconFile);
 326 
 327         pb = new ProcessBuilder("osascript",
 328                 getConfig_VolumeScript(params).getAbsolutePath());
 329         IOUtils.exec(pb);


 330 
 331         // Indicate that we want a custom icon
 332         // NB: attributes of the root directory are ignored
 333         // when creating the volume
 334         // Therefore we have to do this after we mount image
 335         String setFileUtility = findSetFileUtility();
 336         if (setFileUtility != null) {
 337                 //can not find utility => keep going without icon
 338             try {
 339                 volumeIconFile.setWritable(true);
 340                 // The "creator" attribute on a file is a legacy attribute
 341                 // but it seems Finder excepts these bytes to be
 342                 // "icnC" for the volume icon
 343                 // http://endrift.com/blog/2010/06/14/dmg-files-volume-icons-cli
 344                 // (might not work on Mac 10.13 with old XCode)
 345                 pb = new ProcessBuilder(
 346                         setFileUtility,
 347                         "-c", "icnC",
 348                         volumeIconFile.getAbsolutePath());
 349                 IOUtils.exec(pb);
 350                 volumeIconFile.setReadOnly();
 351 
 352                 pb = new ProcessBuilder(
 353                         setFileUtility,
 354                         "-a", "C",
 355                         mountedRoot.getAbsolutePath());
 356                 IOUtils.exec(pb);
 357             } catch (IOException ex) {
 358                 Log.error(ex.getMessage());
 359                 Log.verbose("Cannot enable custom icon using SetFile utility");
 360             }
 361         } else {
 362             Log.verbose(I18N.getString("message.setfile.dmg"));
 363         }
 364 











 365         // Detach the temporary image
 366         pb = new ProcessBuilder(
 367                 hdiutil,
 368                 "detach",
 369                 "-force",
 370                 hdiUtilVerbosityFlag,
 371                 mountedRoot.getAbsolutePath());
 372         IOUtils.exec(pb);

 373 
 374         // Compress it to a new image
 375         pb = new ProcessBuilder(
 376                 hdiutil,
 377                 "convert",
 378                 protoDMG.getAbsolutePath(),
 379                 hdiUtilVerbosityFlag,
 380                 "-format", "UDZO",
 381                 "-o", finalDMG.getAbsolutePath());
 382         IOUtils.exec(pb);
 383 
 384         //add license if needed
 385         if (getConfig_LicenseFile(params).exists()) {
 386             //hdiutil unflatten your_image_file.dmg
 387             pb = new ProcessBuilder(
 388                     hdiutil,
 389                     "unflatten",
 390                     finalDMG.getAbsolutePath()
 391             );
 392             IOUtils.exec(pb);




  77         } catch (IOException ex) {
  78             Log.verbose(ex);
  79             throw new PackagerException(ex);
  80         }
  81     }
  82 
  83     private static final String hdiutil = "/usr/bin/hdiutil";
  84 
  85     private void prepareDMGSetupScript(String volumeName,
  86             Map<String, ? super Object> params) throws IOException {
  87         File dmgSetup = getConfig_VolumeScript(params);
  88         Log.verbose(MessageFormat.format(
  89                 I18N.getString("message.preparing-dmg-setup"),
  90                 dmgSetup.getAbsolutePath()));
  91 
  92         //prepare config for exe
  93         Map<String, String> data = new HashMap<>();
  94         data.put("DEPLOY_ACTUAL_VOLUME_NAME", volumeName);
  95         data.put("DEPLOY_APPLICATION_NAME", APP_NAME.fetchFrom(params));
  96 
  97         data.put("DEPLOY_INSTALL_LOCATION", "(path to applications folder)");
  98         data.put("DEPLOY_INSTALL_NAME", "Applications");
  99 
 100         try (Writer w = Files.newBufferedWriter(dmgSetup.toPath())) {
 101             w.write(preprocessTextResource(dmgSetup.getName(),
 102                     I18N.getString("resource.dmg-setup-script"),
 103                     DEFAULT_DMG_SETUP_SCRIPT, data, VERBOSE.fetchFrom(params),
 104                     RESOURCE_DIR.fetchFrom(params)));
 105         }
 106     }
 107 
 108     private File getConfig_VolumeScript(Map<String, ? super Object> params) {
 109         return new File(CONFIG_ROOT.fetchFrom(params),
 110                 APP_NAME.fetchFrom(params) + "-dmg-setup.scpt");
 111     }
 112 
 113     private File getConfig_VolumeBackground(
 114             Map<String, ? super Object> params) {
 115         return new File(CONFIG_ROOT.fetchFrom(params),
 116                 APP_NAME.fetchFrom(params) + "-background.png");
 117     }
 118 


 302                 hdiUtilVerbosityFlag,
 303                 "-srcfolder", srcFolder.getAbsolutePath(),
 304                 "-volname", APP_NAME.fetchFrom(params),
 305                 "-ov", protoDMG.getAbsolutePath(),
 306                 "-fs", "HFS+",
 307                 "-format", "UDRW");
 308         IOUtils.exec(pb);
 309 
 310         // mount temp image
 311         pb = new ProcessBuilder(
 312                 hdiutil,
 313                 "attach",
 314                 protoDMG.getAbsolutePath(),
 315                 hdiUtilVerbosityFlag,
 316                 "-mountroot", imagesRoot.getAbsolutePath());
 317         IOUtils.exec(pb);
 318 
 319         File mountedRoot = new File(imagesRoot.getAbsolutePath(),
 320                     APP_NAME.fetchFrom(params));
 321 
 322         try {
 323             // volume icon
 324             File volumeIconFile = new File(mountedRoot, ".VolumeIcon.icns");
 325             IOUtils.copyFile(getConfig_VolumeIcon(params),
 326                     volumeIconFile);
 327 
 328             // background image
 329             File bgdir = new File(mountedRoot, ".background");
 330             bgdir.mkdirs();
 331             IOUtils.copyFile(getConfig_VolumeBackground(params),
 332                     new File(bgdir, "background.png"));
 333 
 334             // Indicate that we want a custom icon
 335             // NB: attributes of the root directory are ignored
 336             // when creating the volume
 337             // Therefore we have to do this after we mount image
 338             String setFileUtility = findSetFileUtility();
 339             if (setFileUtility != null) {
 340                 //can not find utility => keep going without icon
 341                 try {
 342                     volumeIconFile.setWritable(true);
 343                     // The "creator" attribute on a file is a legacy attribute
 344                     // but it seems Finder excepts these bytes to be
 345                     // "icnC" for the volume icon
 346                     // http://endrift.com/blog/2010/06/14/dmg-files-volume-icons-cli
 347                     // (might not work on Mac 10.13 with old XCode)
 348                     pb = new ProcessBuilder(
 349                             setFileUtility,
 350                             "-c", "icnC",
 351                             volumeIconFile.getAbsolutePath());
 352                     IOUtils.exec(pb);
 353                     volumeIconFile.setReadOnly();
 354 
 355                     pb = new ProcessBuilder(
 356                             setFileUtility,
 357                             "-a", "C",
 358                             mountedRoot.getAbsolutePath());
 359                     IOUtils.exec(pb);
 360                 } catch (IOException ex) {
 361                     Log.error(ex.getMessage());
 362                     Log.verbose("Cannot enable custom icon using SetFile utility");
 363                 }
 364             } else {
 365                 Log.verbose(I18N.getString("message.setfile.dmg"));
 366             }
 367 
 368             // We will not consider setting background image and creating link to
 369             // /Application folder in DMG as critical error, since it can fail in
 370             // headless enviroment.
 371             try {
 372                 pb = new ProcessBuilder("osascript",
 373                         getConfig_VolumeScript(params).getAbsolutePath());
 374                 IOUtils.exec(pb);
 375             } catch (IOException ex) {
 376                 Log.verbose(ex);
 377             }
 378         } finally {
 379             // Detach the temporary image
 380             pb = new ProcessBuilder(
 381                     hdiutil,
 382                     "detach",
 383                     "-force",
 384                     hdiUtilVerbosityFlag,
 385                     mountedRoot.getAbsolutePath());
 386             IOUtils.exec(pb);
 387         }
 388 
 389         // Compress it to a new image
 390         pb = new ProcessBuilder(
 391                 hdiutil,
 392                 "convert",
 393                 protoDMG.getAbsolutePath(),
 394                 hdiUtilVerbosityFlag,
 395                 "-format", "UDZO",
 396                 "-o", finalDMG.getAbsolutePath());
 397         IOUtils.exec(pb);
 398 
 399         //add license if needed
 400         if (getConfig_LicenseFile(params).exists()) {
 401             //hdiutil unflatten your_image_file.dmg
 402             pb = new ProcessBuilder(
 403                     hdiutil,
 404                     "unflatten",
 405                     finalDMG.getAbsolutePath()
 406             );
 407             IOUtils.exec(pb);


< prev index next >