135 136 private static String getLauncherName(Map<String, ? super Object> params) { 137 return APP_NAME.fetchFrom(params) + ".exe"; 138 } 139 140 // Returns launcher resource name for launcher we need to use. 141 public static String getLauncherResourceName( 142 Map<String, ? super Object> params) { 143 if (CONSOLE_HINT.fetchFrom(params)) { 144 return "jpackageapplauncher.exe"; 145 } else { 146 return "jpackageapplauncherw.exe"; 147 } 148 } 149 150 public static String getLauncherCfgName( 151 Map<String, ? super Object> params) { 152 return "app/" + APP_NAME.fetchFrom(params) +".cfg"; 153 } 154 155 private File getConfig_AppIcon(Map<String, ? super Object> params) { 156 return new File(getConfigRoot(params), 157 APP_NAME.fetchFrom(params) + ".ico"); 158 } 159 160 private File getConfig_ExecutableProperties( 161 Map<String, ? super Object> params) { 162 return new File(getConfigRoot(params), 163 APP_NAME.fetchFrom(params) + ".properties"); 164 } 165 166 File getConfigRoot(Map<String, ? super Object> params) { 167 return CONFIG_ROOT.fetchFrom(params); 168 } 169 170 @Override 171 public Path getAppDir() { 172 return appDir; 173 } 174 175 @Override 176 public Path getAppModsDir() { 177 return appModsDir; 178 } 179 180 @Override 181 public void prepareApplicationFiles(Map<String, ? super Object> params) 182 throws IOException { 183 Map<String, ? super Object> originalParams = new HashMap<>(params); 184 185 try { 186 IOUtils.writableOutputDir(root); 187 IOUtils.writableOutputDir(binDir); 188 } catch (PackagerException pe) { 189 throw new RuntimeException(pe); 190 } 191 AppImageFile.save(root, params); 192 193 // create the .exe launchers 194 createLauncherForEntryPoint(params); 195 196 // copy the jars 197 copyApplication(params); 198 199 // copy in the needed libraries 200 try (InputStream is_lib = getResourceAsStream(LIBRARY_NAME)) { 201 Files.copy(is_lib, binDir.resolve(LIBRARY_NAME)); 202 } 203 204 copyMSVCDLLs(); 205 206 // create the additional launcher(s), if any 207 List<Map<String, ? super Object>> entryPoints = 208 StandardBundlerParam.ADD_LAUNCHERS.fetchFrom(params); 209 for (Map<String, ? super Object> entryPoint : entryPoints) { 210 createLauncherForEntryPoint( 211 AddLauncherArguments.merge(originalParams, entryPoint)); 212 } 213 } 214 215 @Override 216 public void prepareJreFiles(Map<String, ? super Object> params) 217 throws IOException {} 218 219 private void copyMSVCDLLs() throws IOException { 220 AtomicReference<IOException> ioe = new AtomicReference<>(); 221 try (Stream<Path> files = Files.list(runtimeDir.resolve("bin"))) { 222 files.filter(p -> Pattern.matches( 223 "^(vcruntime|msvcp|msvcr|ucrtbase|api-ms-win-).*\\.dll$", 224 p.toFile().getName().toLowerCase())) 225 .forEach(p -> { 226 try { 227 Files.copy(p, binDir.resolve((p.toFile().getName()))); 228 } catch (IOException e) { 229 ioe.set(e); 230 } 231 }); 255 Map<String, ? super Object> params) throws IOException { 256 257 Map<String, String> data = new HashMap<>(); 258 259 // mapping Java parameters in strings for version resource 260 validateValueAndPut(data, "COMPANY_NAME", VENDOR, params); 261 validateValueAndPut(data, "FILE_DESCRIPTION", DESCRIPTION, params); 262 validateValueAndPut(data, "FILE_VERSION", VERSION, params); 263 data.put("INTERNAL_NAME", getLauncherName(params)); 264 validateValueAndPut(data, "LEGAL_COPYRIGHT", COPYRIGHT, params); 265 data.put("ORIGINAL_FILENAME", getLauncherName(params)); 266 validateValueAndPut(data, "PRODUCT_NAME", APP_NAME, params); 267 validateValueAndPut(data, "PRODUCT_VERSION", VERSION, params); 268 269 createResource(EXECUTABLE_PROPERTIES_TEMPLATE, params) 270 .setCategory(I18N.getString("resource.executable-properties-template")) 271 .setSubstitutionData(data) 272 .saveToFile(getConfig_ExecutableProperties(params)); 273 } 274 275 private void createLauncherForEntryPoint( 276 Map<String, ? super Object> params) throws IOException { 277 278 File iconTarget = getConfig_AppIcon(params); 279 280 createResource(TEMPLATE_APP_ICON, params) 281 .setCategory("icon") 282 .setExternal(ICON_ICO.fetchFrom(params)) 283 .saveToFile(iconTarget); 284 285 writeCfgFile(params, root.resolve( 286 getLauncherCfgName(params)).toFile()); 287 288 prepareExecutableProperties(params); 289 290 // Copy executable to bin folder 291 Path executableFile = binDir.resolve(getLauncherName(params)); 292 293 try (InputStream is_launcher = 294 getResourceAsStream(getLauncherResourceName(params))) { 295 writeEntry(is_launcher, executableFile); 296 } 297 298 File launcher = executableFile.toFile(); 299 launcher.setWritable(true, true); 300 301 // Update branding of EXE file 302 if (REBRAND_EXECUTABLE.fetchFrom(params)) { 303 try { 304 String tempDirectory = WindowsDefender.getUserTempDirectory(); 305 if (Arguments.CLIOptions.context().userProvidedBuildRoot) { 306 tempDirectory = 307 TEMP_ROOT.fetchFrom(params).getAbsolutePath(); 308 } 309 if (WindowsDefender.isThereAPotentialWindowsDefenderIssue( 310 tempDirectory)) { 311 Log.verbose(MessageFormat.format(I18N.getString( 312 "message.potential.windows.defender.issue"), 313 tempDirectory)); 314 } 315 316 launcher.setWritable(true); 317 318 if (iconTarget.exists()) { 319 iconSwap(iconTarget.getAbsolutePath(), 320 launcher.getAbsolutePath()); 321 } 322 323 File executableProperties = 324 getConfig_ExecutableProperties(params); 325 326 if (executableProperties.exists()) { 327 if (versionSwap(executableProperties.getAbsolutePath(), 328 launcher.getAbsolutePath()) != 0) { 329 throw new RuntimeException(MessageFormat.format( 330 I18N.getString("error.version-swap"), 331 executableProperties.getAbsolutePath())); 332 } 333 } 334 } finally { 335 executableFile.toFile().setExecutable(true); 336 executableFile.toFile().setReadOnly(); 337 } 338 } 339 340 Files.copy(iconTarget.toPath(), 341 binDir.resolve(APP_NAME.fetchFrom(params) + ".ico")); 342 } 343 344 private void copyApplication(Map<String, ? super Object> params) 345 throws IOException { 346 List<RelativeFileSet> appResourcesList = 347 APP_RESOURCES_LIST.fetchFrom(params); 348 if (appResourcesList == null) { 349 throw new RuntimeException("Null app resources?"); 350 } 351 for (RelativeFileSet appResources : appResourcesList) { 352 if (appResources == null) { 353 throw new RuntimeException("Null app resources?"); 354 } 355 File srcdir = appResources.getBaseDirectory(); 356 for (String fname : appResources.getIncludedFiles()) { 357 copyEntry(appDir, srcdir, fname); 358 } 359 } 360 } 361 | 135 136 private static String getLauncherName(Map<String, ? super Object> params) { 137 return APP_NAME.fetchFrom(params) + ".exe"; 138 } 139 140 // Returns launcher resource name for launcher we need to use. 141 public static String getLauncherResourceName( 142 Map<String, ? super Object> params) { 143 if (CONSOLE_HINT.fetchFrom(params)) { 144 return "jpackageapplauncher.exe"; 145 } else { 146 return "jpackageapplauncherw.exe"; 147 } 148 } 149 150 public static String getLauncherCfgName( 151 Map<String, ? super Object> params) { 152 return "app/" + APP_NAME.fetchFrom(params) +".cfg"; 153 } 154 155 private File getConfig_ExecutableProperties( 156 Map<String, ? super Object> params) { 157 return new File(getConfigRoot(params), 158 APP_NAME.fetchFrom(params) + ".properties"); 159 } 160 161 File getConfigRoot(Map<String, ? super Object> params) { 162 return CONFIG_ROOT.fetchFrom(params); 163 } 164 165 @Override 166 public Path getAppDir() { 167 return appDir; 168 } 169 170 @Override 171 public Path getAppModsDir() { 172 return appModsDir; 173 } 174 175 @Override 176 public void prepareApplicationFiles(Map<String, ? super Object> params) 177 throws IOException { 178 try { 179 IOUtils.writableOutputDir(root); 180 IOUtils.writableOutputDir(binDir); 181 } catch (PackagerException pe) { 182 throw new RuntimeException(pe); 183 } 184 AppImageFile.save(root, params); 185 186 // create the .exe launchers 187 createLauncherForEntryPoint(params, null); 188 189 // copy the jars 190 copyApplication(params); 191 192 // copy in the needed libraries 193 try (InputStream is_lib = getResourceAsStream(LIBRARY_NAME)) { 194 Files.copy(is_lib, binDir.resolve(LIBRARY_NAME)); 195 } 196 197 copyMSVCDLLs(); 198 199 // create the additional launcher(s), if any 200 List<Map<String, ? super Object>> entryPoints = 201 StandardBundlerParam.ADD_LAUNCHERS.fetchFrom(params); 202 for (Map<String, ? super Object> entryPoint : entryPoints) { 203 createLauncherForEntryPoint(AddLauncherArguments.merge(params, 204 entryPoint, ICON.getID(), ICON_ICO.getID()), params); 205 } 206 } 207 208 @Override 209 public void prepareJreFiles(Map<String, ? super Object> params) 210 throws IOException {} 211 212 private void copyMSVCDLLs() throws IOException { 213 AtomicReference<IOException> ioe = new AtomicReference<>(); 214 try (Stream<Path> files = Files.list(runtimeDir.resolve("bin"))) { 215 files.filter(p -> Pattern.matches( 216 "^(vcruntime|msvcp|msvcr|ucrtbase|api-ms-win-).*\\.dll$", 217 p.toFile().getName().toLowerCase())) 218 .forEach(p -> { 219 try { 220 Files.copy(p, binDir.resolve((p.toFile().getName()))); 221 } catch (IOException e) { 222 ioe.set(e); 223 } 224 }); 248 Map<String, ? super Object> params) throws IOException { 249 250 Map<String, String> data = new HashMap<>(); 251 252 // mapping Java parameters in strings for version resource 253 validateValueAndPut(data, "COMPANY_NAME", VENDOR, params); 254 validateValueAndPut(data, "FILE_DESCRIPTION", DESCRIPTION, params); 255 validateValueAndPut(data, "FILE_VERSION", VERSION, params); 256 data.put("INTERNAL_NAME", getLauncherName(params)); 257 validateValueAndPut(data, "LEGAL_COPYRIGHT", COPYRIGHT, params); 258 data.put("ORIGINAL_FILENAME", getLauncherName(params)); 259 validateValueAndPut(data, "PRODUCT_NAME", APP_NAME, params); 260 validateValueAndPut(data, "PRODUCT_VERSION", VERSION, params); 261 262 createResource(EXECUTABLE_PROPERTIES_TEMPLATE, params) 263 .setCategory(I18N.getString("resource.executable-properties-template")) 264 .setSubstitutionData(data) 265 .saveToFile(getConfig_ExecutableProperties(params)); 266 } 267 268 private void createLauncherForEntryPoint(Map<String, ? super Object> params, 269 Map<String, ? super Object> mainParams) throws IOException { 270 271 var iconResource = createIconResource(TEMPLATE_APP_ICON, ICON_ICO, params, 272 mainParams); 273 Path iconTarget = null; 274 if (iconResource != null) { 275 iconTarget = binDir.resolve(APP_NAME.fetchFrom(params) + ".ico"); 276 if (null == iconResource.saveToFile(iconTarget)) { 277 iconTarget = null; 278 } 279 } 280 281 writeCfgFile(params, root.resolve( 282 getLauncherCfgName(params)).toFile()); 283 284 prepareExecutableProperties(params); 285 286 // Copy executable to bin folder 287 Path executableFile = binDir.resolve(getLauncherName(params)); 288 289 try (InputStream is_launcher = 290 getResourceAsStream(getLauncherResourceName(params))) { 291 writeEntry(is_launcher, executableFile); 292 } 293 294 File launcher = executableFile.toFile(); 295 launcher.setWritable(true, true); 296 297 // Update branding of EXE file 298 if (REBRAND_EXECUTABLE.fetchFrom(params)) { 299 try { 300 String tempDirectory = WindowsDefender.getUserTempDirectory(); 301 if (Arguments.CLIOptions.context().userProvidedBuildRoot) { 302 tempDirectory = 303 TEMP_ROOT.fetchFrom(params).getAbsolutePath(); 304 } 305 if (WindowsDefender.isThereAPotentialWindowsDefenderIssue( 306 tempDirectory)) { 307 Log.verbose(MessageFormat.format(I18N.getString( 308 "message.potential.windows.defender.issue"), 309 tempDirectory)); 310 } 311 312 launcher.setWritable(true); 313 314 if (iconTarget != null) { 315 iconSwap(iconTarget.toAbsolutePath().toString(), 316 launcher.getAbsolutePath()); 317 } 318 319 File executableProperties = 320 getConfig_ExecutableProperties(params); 321 322 if (executableProperties.exists()) { 323 if (versionSwap(executableProperties.getAbsolutePath(), 324 launcher.getAbsolutePath()) != 0) { 325 throw new RuntimeException(MessageFormat.format( 326 I18N.getString("error.version-swap"), 327 executableProperties.getAbsolutePath())); 328 } 329 } 330 } finally { 331 executableFile.toFile().setExecutable(true); 332 executableFile.toFile().setReadOnly(); 333 } 334 } 335 } 336 337 private void copyApplication(Map<String, ? super Object> params) 338 throws IOException { 339 List<RelativeFileSet> appResourcesList = 340 APP_RESOURCES_LIST.fetchFrom(params); 341 if (appResourcesList == null) { 342 throw new RuntimeException("Null app resources?"); 343 } 344 for (RelativeFileSet appResources : appResourcesList) { 345 if (appResources == null) { 346 throw new RuntimeException("Null app resources?"); 347 } 348 File srcdir = appResources.getBaseDirectory(); 349 for (String fname : appResources.getIncludedFiles()) { 350 copyEntry(appDir, srcdir, fname); 351 } 352 } 353 } 354 |