10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.jpackage.internal; 27 28 import java.io.File; 29 import java.io.FileOutputStream; 30 import java.io.FileInputStream; 31 import java.io.IOException; 32 import java.io.InputStream; 33 import java.io.OutputStream; 34 import java.io.OutputStreamWriter; 35 import java.io.UncheckedIOException; 36 import java.io.Writer; 37 import java.io.BufferedWriter; 38 import java.io.FileWriter; 39 import java.nio.file.Files; 40 import java.nio.file.Path; 41 import java.nio.file.StandardCopyOption; 42 import java.nio.file.attribute.PosixFilePermission; 43 import java.text.MessageFormat; 44 import java.util.HashMap; 45 import java.util.List; 46 import java.util.Map; 47 import java.util.Objects; 48 import java.util.ResourceBundle; 49 import java.util.Set; 50 import java.util.concurrent.atomic.AtomicReference; 51 import java.util.regex.Pattern; 52 import java.util.stream.Stream; 53 import jdk.jpackage.internal.Arguments; 54 55 import static jdk.jpackage.internal.StandardBundlerParam.*; 56 57 public class WindowsAppImageBuilder extends AbstractAppImageBuilder { 58 59 private static final ResourceBundle I18N = ResourceBundle.getBundle( 60 "jdk.jpackage.internal.resources.WinResources"); 61 62 private final static String LIBRARY_NAME = "applauncher.dll"; 63 private final static String REDIST_MSVCR = "vcruntimeVS_VER.dll"; 64 private final static String REDIST_MSVCP = "msvcpVS_VER.dll"; 65 66 private final static String TEMPLATE_APP_ICON ="javalogo_white_48.ico"; 67 68 private static final String EXECUTABLE_PROPERTIES_TEMPLATE = 69 "WinLauncher.template"; 70 71 private final Path root; 72 private final Path appDir; 73 private final Path appModsDir; 74 private final Path runtimeDir; 75 private final Path mdir; 76 77 private final Map<String, ? super Object> params; 78 371 Files.copy(in, iconTarget.toPath(), 372 StandardCopyOption.REPLACE_EXISTING); 373 374 writeCfgFile(p, root.resolve( 375 getLauncherCfgName(p)).toFile(), "$APPDIR\\runtime"); 376 377 prepareExecutableProperties(p); 378 379 // Copy executable root folder 380 Path executableFile = root.resolve(getLauncherName(p)); 381 try (InputStream is_launcher = 382 getResourceAsStream(getLauncherResourceName(p))) { 383 writeEntry(is_launcher, executableFile); 384 } 385 386 File launcher = executableFile.toFile(); 387 launcher.setWritable(true, true); 388 389 // Update branding of EXE file 390 if (REBRAND_EXECUTABLE.fetchFrom(p)) { 391 File tool = new File( 392 System.getProperty("java.home") + "\\bin\\jpackage.exe"); 393 394 // Run tool on launcher file to change the icon and the metadata. 395 try { 396 if (WindowsDefender.isThereAPotentialWindowsDefenderIssue()) { 397 Log.error(MessageFormat.format(I18N.getString( 398 "message.potential.windows.defender.issue"), 399 WindowsDefender.getUserTempDirectory())); 400 } 401 402 launcher.setWritable(true); 403 404 if (iconTarget.exists()) { 405 ProcessBuilder pb = new ProcessBuilder( 406 tool.getAbsolutePath(), 407 "--icon-swap", 408 iconTarget.getAbsolutePath(), 409 launcher.getAbsolutePath()); 410 IOUtils.exec(pb, false); 411 } 412 413 File executableProperties = getConfig_ExecutableProperties(p); 414 415 if (executableProperties.exists()) { 416 ProcessBuilder pb = new ProcessBuilder( 417 tool.getAbsolutePath(), 418 "--version-swap", 419 executableProperties.getAbsolutePath(), 420 launcher.getAbsolutePath()); 421 IOUtils.exec(pb, false); 422 } 423 } 424 finally { 425 executableFile.toFile().setReadOnly(); 426 } 427 } 428 429 Files.copy(iconTarget.toPath(), 430 root.resolve(APP_NAME.fetchFrom(p) + ".ico")); 431 } 432 433 private void copyApplication(Map<String, ? super Object> params) 434 throws IOException { 435 List<RelativeFileSet> appResourcesList = 436 APP_RESOURCES_LIST.fetchFrom(params); 437 if (appResourcesList == null) { 438 throw new RuntimeException("Null app resources?"); 439 } 440 for (RelativeFileSet appResources : appResourcesList) { 441 if (appResources == null) { 442 throw new RuntimeException("Null app resources?"); 443 } 444 File srcdir = appResources.getBaseDirectory(); 445 for (String fname : appResources.getIncludedFiles()) { 446 copyEntry(appDir, srcdir, fname); 447 } 448 } 449 } 450 451 } | 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.jpackage.internal; 27 28 import java.io.File; 29 import java.io.FileOutputStream; 30 import java.io.IOException; 31 import java.io.InputStream; 32 import java.io.OutputStream; 33 import java.io.OutputStreamWriter; 34 import java.io.UncheckedIOException; 35 import java.io.Writer; 36 import java.io.BufferedWriter; 37 import java.io.FileWriter; 38 import java.nio.file.Files; 39 import java.nio.file.Path; 40 import java.nio.file.StandardCopyOption; 41 import java.nio.file.attribute.PosixFilePermission; 42 import java.text.MessageFormat; 43 import java.util.HashMap; 44 import java.util.List; 45 import java.util.Map; 46 import java.util.Objects; 47 import java.util.ResourceBundle; 48 import java.util.Set; 49 import java.util.concurrent.atomic.AtomicReference; 50 import java.util.regex.Pattern; 51 import java.util.stream.Stream; 52 53 import static jdk.jpackage.internal.StandardBundlerParam.*; 54 55 public class WindowsAppImageBuilder extends AbstractAppImageBuilder { 56 57 static { 58 System.loadLibrary("jpackage"); 59 } 60 61 private static final ResourceBundle I18N = ResourceBundle.getBundle( 62 "jdk.jpackage.internal.resources.WinResources"); 63 64 private final static String LIBRARY_NAME = "applauncher.dll"; 65 private final static String REDIST_MSVCR = "vcruntimeVS_VER.dll"; 66 private final static String REDIST_MSVCP = "msvcpVS_VER.dll"; 67 68 private final static String TEMPLATE_APP_ICON ="javalogo_white_48.ico"; 69 70 private static final String EXECUTABLE_PROPERTIES_TEMPLATE = 71 "WinLauncher.template"; 72 73 private final Path root; 74 private final Path appDir; 75 private final Path appModsDir; 76 private final Path runtimeDir; 77 private final Path mdir; 78 79 private final Map<String, ? super Object> params; 80 373 Files.copy(in, iconTarget.toPath(), 374 StandardCopyOption.REPLACE_EXISTING); 375 376 writeCfgFile(p, root.resolve( 377 getLauncherCfgName(p)).toFile(), "$APPDIR\\runtime"); 378 379 prepareExecutableProperties(p); 380 381 // Copy executable root folder 382 Path executableFile = root.resolve(getLauncherName(p)); 383 try (InputStream is_launcher = 384 getResourceAsStream(getLauncherResourceName(p))) { 385 writeEntry(is_launcher, executableFile); 386 } 387 388 File launcher = executableFile.toFile(); 389 launcher.setWritable(true, true); 390 391 // Update branding of EXE file 392 if (REBRAND_EXECUTABLE.fetchFrom(p)) { 393 try { 394 String tempDirectory = WindowsDefender.getUserTempDirectory(); 395 if (Arguments.CLIOptions.context().userProvidedBuildRoot) { 396 tempDirectory = BUILD_ROOT.fetchFrom(p).getAbsolutePath(); 397 } 398 if (WindowsDefender.isThereAPotentialWindowsDefenderIssue( 399 tempDirectory)) { 400 Log.error(MessageFormat.format(I18N.getString( 401 "message.potential.windows.defender.issue"), 402 tempDirectory)); 403 } 404 405 launcher.setWritable(true); 406 407 if (iconTarget.exists()) { 408 iconSwap(iconTarget.getAbsolutePath(), 409 launcher.getAbsolutePath()); 410 } 411 412 File executableProperties = getConfig_ExecutableProperties(p); 413 414 if (executableProperties.exists()) { 415 versionSwap(executableProperties.getAbsolutePath(), 416 launcher.getAbsolutePath()); 417 } 418 } finally { 419 executableFile.toFile().setReadOnly(); 420 } 421 } 422 423 Files.copy(iconTarget.toPath(), 424 root.resolve(APP_NAME.fetchFrom(p) + ".ico")); 425 } 426 427 private void copyApplication(Map<String, ? super Object> params) 428 throws IOException { 429 List<RelativeFileSet> appResourcesList = 430 APP_RESOURCES_LIST.fetchFrom(params); 431 if (appResourcesList == null) { 432 throw new RuntimeException("Null app resources?"); 433 } 434 for (RelativeFileSet appResources : appResourcesList) { 435 if (appResources == null) { 436 throw new RuntimeException("Null app resources?"); 437 } 438 File srcdir = appResources.getBaseDirectory(); 439 for (String fname : appResources.getIncludedFiles()) { 440 copyEntry(appDir, srcdir, fname); 441 } 442 } 443 } 444 445 private static native int iconSwap(String iconTarget, String launcher); 446 447 private static native int versionSwap(String executableProperties, String launcher); 448 449 } |