57
58 static {
59 System.loadLibrary("jpackage");
60 }
61
62 private static final ResourceBundle I18N = ResourceBundle.getBundle(
63 "jdk.jpackage.internal.resources.WinResources");
64
65 private final static String LIBRARY_NAME = "applauncher.dll";
66 private final static String REDIST_MSVCR = "vcruntimeVS_VER.dll";
67 private final static String REDIST_MSVCP = "msvcpVS_VER.dll";
68
69 private final static String TEMPLATE_APP_ICON ="javalogo_white_48.ico";
70
71 private static final String EXECUTABLE_PROPERTIES_TEMPLATE =
72 "WinLauncher.template";
73
74 private final Path root;
75 private final Path appDir;
76 private final Path appModsDir;
77 private final String relativeModsDir;
78 private final Path runtimeDir;
79 private final Path mdir;
80 private final Path binDir;
81
82 private final Map<String, ? super Object> params;
83
84 public static final BundlerParamInfo<Boolean> REBRAND_EXECUTABLE =
85 new WindowsBundlerParam<>(
86 "win.launcher.rebrand",
87 Boolean.class,
88 params -> Boolean.TRUE,
89 (s, p) -> Boolean.valueOf(s));
90
91 public static final BundlerParamInfo<File> ICON_ICO =
92 new StandardBundlerParam<>(
93 "icon.ico",
94 File.class,
95 params -> {
96 File f = ICON.fetchFrom(params);
97 if (f != null && !f.getName().toLowerCase().endsWith(".ico")) {
108 Arguments.CLIOptions.WIN_CONSOLE_HINT.getId(),
109 Boolean.class,
110 params -> false,
111 // valueOf(null) is false,
112 // and we actually do want null in some cases
113 (s, p) -> (s == null
114 || "null".equalsIgnoreCase(s)) ? true : Boolean.valueOf(s));
115
116 public WindowsAppImageBuilder(Map<String, Object> config, Path imageOutDir)
117 throws IOException {
118 super(config,
119 imageOutDir.resolve(APP_NAME.fetchFrom(config) + "/runtime"));
120
121 Objects.requireNonNull(imageOutDir);
122
123 this.params = config;
124
125 this.root = imageOutDir.resolve(APP_NAME.fetchFrom(params));
126 this.appDir = root.resolve("app");
127 this.appModsDir = appDir.resolve("mods");
128 this.relativeModsDir = "app/mods";
129 this.runtimeDir = root.resolve("runtime");
130 this.mdir = runtimeDir.resolve("lib");
131 this.binDir = root.resolve("bin");
132 Files.createDirectories(appDir);
133 Files.createDirectories(runtimeDir);
134 }
135
136 public WindowsAppImageBuilder(String jreName, Path imageOutDir)
137 throws IOException {
138 super(null, imageOutDir.resolve(jreName));
139
140 Objects.requireNonNull(imageOutDir);
141
142 this.params = null;
143 this.root = imageOutDir.resolve(jreName);
144 this.appDir = null;
145 this.appModsDir = null;
146 this.relativeModsDir = null;
147 this.runtimeDir = root;
148 this.mdir = runtimeDir.resolve("lib");
149 this.binDir = null;
150 Files.createDirectories(runtimeDir);
151 }
152
153 private void writeEntry(InputStream in, Path dstFile) throws IOException {
154 Files.createDirectories(dstFile.getParent());
155 Files.copy(in, dstFile);
156 }
157
158 private static String getLauncherName(Map<String, ? super Object> params) {
159 return APP_NAME.fetchFrom(params) + ".exe";
160 }
161
162 // Returns launcher resource name for launcher we need to use.
163 public static String getLauncherResourceName(
164 Map<String, ? super Object> params) {
165 if (CONSOLE_HINT.fetchFrom(params)) {
166 return "jpackageapplauncher.exe";
183 Map<String, ? super Object> params) {
184 return new File(getConfigRoot(params),
185 APP_NAME.fetchFrom(params) + ".properties");
186 }
187
188 File getConfigRoot(Map<String, ? super Object> params) {
189 return CONFIG_ROOT.fetchFrom(params);
190 }
191
192 @Override
193 public Path getAppDir() {
194 return appDir;
195 }
196
197 @Override
198 public Path getAppModsDir() {
199 return appModsDir;
200 }
201
202 @Override
203 public String getRelativeModsDir() {
204 return relativeModsDir;
205 }
206
207 @Override
208 public void prepareApplicationFiles() throws IOException {
209 Map<String, ? super Object> originalParams = new HashMap<>(params);
210
211 try {
212 IOUtils.writableOutputDir(root);
213 IOUtils.writableOutputDir(binDir);
214 } catch (PackagerException pe) {
215 throw new RuntimeException(pe);
216 }
217
218 // create the .exe launchers
219 createLauncherForEntryPoint(params);
220
221 // copy the jars
222 copyApplication(params);
223
224 // copy in the needed libraries
225 try (InputStream is_lib = getResourceAsStream(LIBRARY_NAME)) {
226 Files.copy(is_lib, binDir.resolve(LIBRARY_NAME));
227 }
305 private void createLauncherForEntryPoint(
306 Map<String, ? super Object> params) throws IOException {
307
308 File launcherIcon = ICON_ICO.fetchFrom(params);
309 File icon = launcherIcon != null ?
310 launcherIcon : ICON_ICO.fetchFrom(params);
311 File iconTarget = getConfig_AppIcon(params);
312
313 InputStream in = locateResource(
314 APP_NAME.fetchFrom(params) + ".ico",
315 "icon",
316 TEMPLATE_APP_ICON,
317 icon,
318 VERBOSE.fetchFrom(params),
319 RESOURCE_DIR.fetchFrom(params));
320
321 Files.copy(in, iconTarget.toPath(),
322 StandardCopyOption.REPLACE_EXISTING);
323
324 writeCfgFile(params, root.resolve(
325 getLauncherCfgName(params)).toFile(), "$APPDIR\\runtime");
326
327 prepareExecutableProperties(params);
328
329 // Copy executable to bin folder
330 Path executableFile = binDir.resolve(getLauncherName(params));
331
332 try (InputStream is_launcher =
333 getResourceAsStream(getLauncherResourceName(params))) {
334 writeEntry(is_launcher, executableFile);
335 }
336
337 File launcher = executableFile.toFile();
338 launcher.setWritable(true, true);
339
340 // Update branding of EXE file
341 if (REBRAND_EXECUTABLE.fetchFrom(params)) {
342 try {
343 String tempDirectory = WindowsDefender.getUserTempDirectory();
344 if (Arguments.CLIOptions.context().userProvidedBuildRoot) {
345 tempDirectory =
|
57
58 static {
59 System.loadLibrary("jpackage");
60 }
61
62 private static final ResourceBundle I18N = ResourceBundle.getBundle(
63 "jdk.jpackage.internal.resources.WinResources");
64
65 private final static String LIBRARY_NAME = "applauncher.dll";
66 private final static String REDIST_MSVCR = "vcruntimeVS_VER.dll";
67 private final static String REDIST_MSVCP = "msvcpVS_VER.dll";
68
69 private final static String TEMPLATE_APP_ICON ="javalogo_white_48.ico";
70
71 private static final String EXECUTABLE_PROPERTIES_TEMPLATE =
72 "WinLauncher.template";
73
74 private final Path root;
75 private final Path appDir;
76 private final Path appModsDir;
77 private final Path runtimeDir;
78 private final Path mdir;
79 private final Path binDir;
80
81 private final Map<String, ? super Object> params;
82
83 public static final BundlerParamInfo<Boolean> REBRAND_EXECUTABLE =
84 new WindowsBundlerParam<>(
85 "win.launcher.rebrand",
86 Boolean.class,
87 params -> Boolean.TRUE,
88 (s, p) -> Boolean.valueOf(s));
89
90 public static final BundlerParamInfo<File> ICON_ICO =
91 new StandardBundlerParam<>(
92 "icon.ico",
93 File.class,
94 params -> {
95 File f = ICON.fetchFrom(params);
96 if (f != null && !f.getName().toLowerCase().endsWith(".ico")) {
107 Arguments.CLIOptions.WIN_CONSOLE_HINT.getId(),
108 Boolean.class,
109 params -> false,
110 // valueOf(null) is false,
111 // and we actually do want null in some cases
112 (s, p) -> (s == null
113 || "null".equalsIgnoreCase(s)) ? true : Boolean.valueOf(s));
114
115 public WindowsAppImageBuilder(Map<String, Object> config, Path imageOutDir)
116 throws IOException {
117 super(config,
118 imageOutDir.resolve(APP_NAME.fetchFrom(config) + "/runtime"));
119
120 Objects.requireNonNull(imageOutDir);
121
122 this.params = config;
123
124 this.root = imageOutDir.resolve(APP_NAME.fetchFrom(params));
125 this.appDir = root.resolve("app");
126 this.appModsDir = appDir.resolve("mods");
127 this.runtimeDir = root.resolve("runtime");
128 this.mdir = runtimeDir.resolve("lib");
129 this.binDir = root.resolve("bin");
130 Files.createDirectories(appDir);
131 Files.createDirectories(runtimeDir);
132 }
133
134 public WindowsAppImageBuilder(String jreName, Path imageOutDir)
135 throws IOException {
136 super(null, imageOutDir.resolve(jreName));
137
138 Objects.requireNonNull(imageOutDir);
139
140 this.params = null;
141 this.root = imageOutDir.resolve(jreName);
142 this.appDir = null;
143 this.appModsDir = null;
144 this.runtimeDir = root;
145 this.mdir = runtimeDir.resolve("lib");
146 this.binDir = null;
147 Files.createDirectories(runtimeDir);
148 }
149
150 private void writeEntry(InputStream in, Path dstFile) throws IOException {
151 Files.createDirectories(dstFile.getParent());
152 Files.copy(in, dstFile);
153 }
154
155 private static String getLauncherName(Map<String, ? super Object> params) {
156 return APP_NAME.fetchFrom(params) + ".exe";
157 }
158
159 // Returns launcher resource name for launcher we need to use.
160 public static String getLauncherResourceName(
161 Map<String, ? super Object> params) {
162 if (CONSOLE_HINT.fetchFrom(params)) {
163 return "jpackageapplauncher.exe";
180 Map<String, ? super Object> params) {
181 return new File(getConfigRoot(params),
182 APP_NAME.fetchFrom(params) + ".properties");
183 }
184
185 File getConfigRoot(Map<String, ? super Object> params) {
186 return CONFIG_ROOT.fetchFrom(params);
187 }
188
189 @Override
190 public Path getAppDir() {
191 return appDir;
192 }
193
194 @Override
195 public Path getAppModsDir() {
196 return appModsDir;
197 }
198
199 @Override
200 public void prepareApplicationFiles() throws IOException {
201 Map<String, ? super Object> originalParams = new HashMap<>(params);
202
203 try {
204 IOUtils.writableOutputDir(root);
205 IOUtils.writableOutputDir(binDir);
206 } catch (PackagerException pe) {
207 throw new RuntimeException(pe);
208 }
209
210 // create the .exe launchers
211 createLauncherForEntryPoint(params);
212
213 // copy the jars
214 copyApplication(params);
215
216 // copy in the needed libraries
217 try (InputStream is_lib = getResourceAsStream(LIBRARY_NAME)) {
218 Files.copy(is_lib, binDir.resolve(LIBRARY_NAME));
219 }
297 private void createLauncherForEntryPoint(
298 Map<String, ? super Object> params) throws IOException {
299
300 File launcherIcon = ICON_ICO.fetchFrom(params);
301 File icon = launcherIcon != null ?
302 launcherIcon : ICON_ICO.fetchFrom(params);
303 File iconTarget = getConfig_AppIcon(params);
304
305 InputStream in = locateResource(
306 APP_NAME.fetchFrom(params) + ".ico",
307 "icon",
308 TEMPLATE_APP_ICON,
309 icon,
310 VERBOSE.fetchFrom(params),
311 RESOURCE_DIR.fetchFrom(params));
312
313 Files.copy(in, iconTarget.toPath(),
314 StandardCopyOption.REPLACE_EXISTING);
315
316 writeCfgFile(params, root.resolve(
317 getLauncherCfgName(params)).toFile());
318
319 prepareExecutableProperties(params);
320
321 // Copy executable to bin folder
322 Path executableFile = binDir.resolve(getLauncherName(params));
323
324 try (InputStream is_launcher =
325 getResourceAsStream(getLauncherResourceName(params))) {
326 writeEntry(is_launcher, executableFile);
327 }
328
329 File launcher = executableFile.toFile();
330 launcher.setWritable(true, true);
331
332 // Update branding of EXE file
333 if (REBRAND_EXECUTABLE.fetchFrom(params)) {
334 try {
335 String tempDirectory = WindowsDefender.getUserTempDirectory();
336 if (Arguments.CLIOptions.context().userProvidedBuildRoot) {
337 tempDirectory =
|