UNPKG

14.7 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.default = void 0;
7
8function _bluebirdLst() {
9 const data = _interopRequireWildcard(require("bluebird-lst"));
10
11 _bluebirdLst = function () {
12 return data;
13 };
14
15 return data;
16}
17
18function _builderUtil() {
19 const data = require("builder-util");
20
21 _builderUtil = function () {
22 return data;
23 };
24
25 return data;
26}
27
28function _builderUtilRuntime() {
29 const data = require("builder-util-runtime");
30
31 _builderUtilRuntime = function () {
32 return data;
33 };
34
35 return data;
36}
37
38function _binDownload() {
39 const data = require("builder-util/out/binDownload");
40
41 _binDownload = function () {
42 return data;
43 };
44
45 return data;
46}
47
48function _fs() {
49 const data = require("builder-util/out/fs");
50
51 _fs = function () {
52 return data;
53 };
54
55 return data;
56}
57
58function _crypto() {
59 const data = require("crypto");
60
61 _crypto = function () {
62 return data;
63 };
64
65 return data;
66}
67
68function ejs() {
69 const data = _interopRequireWildcard(require("ejs"));
70
71 ejs = function () {
72 return data;
73 };
74
75 return data;
76}
77
78function _fsExtraP() {
79 const data = require("fs-extra-p");
80
81 _fsExtraP = function () {
82 return data;
83 };
84
85 return data;
86}
87
88function _lazyVal() {
89 const data = require("lazy-val");
90
91 _lazyVal = function () {
92 return data;
93 };
94
95 return data;
96}
97
98var path = _interopRequireWildcard(require("path"));
99
100function _core() {
101 const data = require("../core");
102
103 _core = function () {
104 return data;
105 };
106
107 return data;
108}
109
110function _CommonWindowsInstallerConfiguration() {
111 const data = require("../options/CommonWindowsInstallerConfiguration");
112
113 _CommonWindowsInstallerConfiguration = function () {
114 return data;
115 };
116
117 return data;
118}
119
120function _pathManager() {
121 const data = require("../util/pathManager");
122
123 _pathManager = function () {
124 return data;
125 };
126
127 return data;
128}
129
130function _vm() {
131 const data = require("../vm/vm");
132
133 _vm = function () {
134 return data;
135 };
136
137 return data;
138}
139
140function _WineVm() {
141 const data = require("../vm/WineVm");
142
143 _WineVm = function () {
144 return data;
145 };
146
147 return data;
148}
149
150function _targetUtil() {
151 const data = require("./targetUtil");
152
153 _targetUtil = function () {
154 return data;
155 };
156
157 return data;
158}
159
160function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
161
162const ELECTRON_BUILDER_UPGRADE_CODE_NS_UUID = _builderUtilRuntime().UUID.parse("d752fe43-5d44-44d5-9fc9-6dd1bf19d5cc");
163
164const ROOT_DIR_ID = "APPLICATIONFOLDER";
165const ASSISTED_UI_FILE_NAME = "WixUI_Assisted.wxs";
166const projectTemplate = new (_lazyVal().Lazy)((0, _bluebirdLst().coroutine)(function* () {
167 const template = (yield (0, _fsExtraP().readFile)(path.join((0, _pathManager().getTemplatePath)("msi"), "template.xml"), "utf8")).replace(/{{/g, "<%").replace(/}}/g, "%>").replace(/\${([^}]+)}/g, "<%=$1%>");
168 return ejs().compile(template);
169})); // WiX doesn't support Mono, so, dontnet462 is required to be installed for wine (preinstalled in our bundled wine)
170
171class MsiTarget extends _core().Target {
172 constructor(packager, outDir) {
173 super("msi");
174 this.packager = packager;
175 this.outDir = outDir;
176 this.vm = process.platform === "win32" ? new (_vm().VmManager)() : new (_WineVm().WineVmManager)();
177 this.options = (0, _builderUtil().deepAssign)(this.packager.platformSpecificBuildOptions, this.packager.config.msi);
178 }
179
180 build(appOutDir, arch) {
181 var _this = this;
182
183 return (0, _bluebirdLst().coroutine)(function* () {
184 const packager = _this.packager;
185 const artifactName = packager.expandArtifactNamePattern(_this.options, "msi", arch);
186 const artifactPath = path.join(_this.outDir, artifactName);
187
188 _this.logBuilding("MSI", artifactPath, arch);
189
190 const stageDir = yield (0, _targetUtil().createStageDir)(_this, packager, arch);
191 const vm = _this.vm;
192 const commonOptions = (0, _CommonWindowsInstallerConfiguration().getEffectiveOptions)(_this.options, _this.packager);
193
194 if (commonOptions.isAssisted) {
195 // F*** *** *** *** *** *** *** *** *** *** *** *** *** WiX *** *** *** *** *** *** *** *** ***
196 // cannot understand how to set MSIINSTALLPERUSER on radio box change. In any case installed per user.
197 _builderUtil().log.warn(`MSI DOESN'T SUPPORT assisted installer. Please use NSIS instead.`);
198 }
199
200 const projectFile = stageDir.getTempFile("project.wxs");
201 const objectFiles = ["project.wixobj"];
202 const uiFile = commonOptions.isAssisted ? stageDir.getTempFile(ASSISTED_UI_FILE_NAME) : null;
203 yield (0, _fsExtraP().writeFile)(projectFile, (yield _this.writeManifest(appOutDir, arch, commonOptions)));
204
205 if (uiFile !== null) {
206 yield (0, _fsExtraP().writeFile)(uiFile, (yield (0, _fsExtraP().readFile)(path.join((0, _pathManager().getTemplatePath)("msi"), ASSISTED_UI_FILE_NAME), "utf8")));
207 objectFiles.push(ASSISTED_UI_FILE_NAME.replace(".wxs", ".wixobj"));
208 } // noinspection SpellCheckingInspection
209
210
211 const vendorPath = yield (0, _binDownload().getBinFromGithub)("wix", "4.0.0.5512.2", "/X5poahdCc3199Vt6AP7gluTlT1nxi9cbbHhZhCMEu+ngyP1LiBMn+oZX7QAZVaKeBMc2SjVp7fJqNLqsUnPNQ=="); // noinspection SpellCheckingInspection
212
213 const candleArgs = ["-arch", arch === _builderUtil().Arch.ia32 ? "x86" : arch === _builderUtil().Arch.armv7l ? "arm" : "x64", `-dappDir=${vm.toVmFile(appOutDir)}`].concat(_this.getCommonWixArgs());
214 candleArgs.push("project.wxs");
215
216 if (uiFile !== null) {
217 candleArgs.push(ASSISTED_UI_FILE_NAME);
218 }
219
220 yield vm.exec(vm.toVmFile(path.join(vendorPath, "candle.exe")), candleArgs, {
221 cwd: stageDir.dir
222 });
223 yield _this.light(objectFiles, vm, artifactPath, appOutDir, vendorPath, stageDir.dir);
224 yield stageDir.cleanup();
225 yield packager.sign(artifactPath);
226 packager.info.dispatchArtifactCreated({
227 file: artifactPath,
228 packager,
229 arch,
230 safeArtifactName: packager.computeSafeArtifactName(artifactName, "msi"),
231 target: _this,
232 isWriteUpdateInfo: false
233 });
234 })();
235 }
236
237 light(objectFiles, vm, artifactPath, appOutDir, vendorPath, tempDir) {
238 var _this2 = this;
239
240 return (0, _bluebirdLst().coroutine)(function* () {
241 // noinspection SpellCheckingInspection
242 const lightArgs = ["-out", vm.toVmFile(artifactPath), "-v", // https://github.com/wixtoolset/issues/issues/5169
243 "-spdb", // https://sourceforge.net/p/wix/bugs/2405/
244 // error LGHT1076 : ICE61: This product should remove only older versions of itself. The Maximum version is not less than the current product. (1.1.0.42 1.1.0.42)
245 "-sw1076", `-dappDir=${vm.toVmFile(appOutDir)}`].concat(_this2.getCommonWixArgs()); // http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/Build-3-5-2229-0-give-me-the-following-error-error-LGHT0216-An-unexpected-Win32-exception-with-errorn-td5707443.html
246
247 if (process.platform !== "win32") {
248 // noinspection SpellCheckingInspection
249 lightArgs.push("-sval");
250 }
251
252 if (_this2.options.oneClick === false) {
253 lightArgs.push("-ext", "WixUIExtension");
254 } // objectFiles - only filenames, we set current directory to our temp stage dir
255
256
257 lightArgs.push(...objectFiles);
258 yield vm.exec(vm.toVmFile(path.join(vendorPath, "light.exe")), lightArgs, {
259 cwd: tempDir
260 });
261 })();
262 }
263
264 getCommonWixArgs() {
265 const args = ["-pedantic"];
266
267 if (this.options.warningsAsErrors !== false) {
268 args.push("-wx");
269 }
270
271 return args;
272 }
273
274 writeManifest(appOutDir, arch, commonOptions) {
275 var _this3 = this;
276
277 return (0, _bluebirdLst().coroutine)(function* () {
278 const appInfo = _this3.packager.appInfo;
279 const {
280 files,
281 dirs
282 } = yield _this3.computeFileDeclaration(appOutDir);
283 const companyName = appInfo.companyName;
284
285 if (!companyName) {
286 _builderUtil().log.warn(`Manufacturer is not set for MSI — please set "author" in the package.json`);
287 }
288
289 const compression = _this3.packager.compression;
290 const options = _this3.options;
291 const iconPath = yield _this3.packager.getIconPath();
292 return (yield projectTemplate.value)(Object.assign({}, commonOptions, {
293 isCreateDesktopShortcut: commonOptions.isCreateDesktopShortcut !== _CommonWindowsInstallerConfiguration().DesktopShortcutCreationPolicy.NEVER,
294 isRunAfterFinish: options.runAfterFinish !== false,
295 iconPath: iconPath == null ? null : _this3.vm.toVmFile(iconPath),
296 compressionLevel: compression === "store" ? "none" : "high",
297 version: appInfo.versionInWeirdWindowsForm,
298 productName: appInfo.productName,
299 upgradeCode: (options.upgradeCode || _builderUtilRuntime().UUID.v5(appInfo.id, ELECTRON_BUILDER_UPGRADE_CODE_NS_UUID)).toUpperCase(),
300 manufacturer: companyName || appInfo.productName,
301 appDescription: appInfo.description,
302 // https://stackoverflow.com/questions/1929038/compilation-error-ice80-the-64bitcomponent-uses-32bitdirectory
303 programFilesId: arch === _builderUtil().Arch.x64 ? "ProgramFiles64Folder" : "ProgramFilesFolder",
304 // wix in the name because special wix format can be used in the name
305 installationDirectoryWixName: (0, _targetUtil().getWindowsInstallationDirName)(appInfo, commonOptions.isPerMachine === true),
306 dirs,
307 files
308 }));
309 })();
310 }
311
312 computeFileDeclaration(appOutDir) {
313 var _this4 = this;
314
315 return (0, _bluebirdLst().coroutine)(function* () {
316 const appInfo = _this4.packager.appInfo;
317 let isRootDirAddedToRemoveTable = false;
318 const dirNames = new Set();
319 const dirs = [];
320 const fileSpace = " ".repeat(6);
321 const commonOptions = (0, _CommonWindowsInstallerConfiguration().getEffectiveOptions)(_this4.options, _this4.packager);
322 const files = yield _bluebirdLst().default.map((0, _fs().walk)(appOutDir), file => {
323 const packagePath = file.substring(appOutDir.length + 1);
324 const lastSlash = packagePath.lastIndexOf(path.sep);
325 const fileName = lastSlash > 0 ? packagePath.substring(lastSlash + 1) : packagePath;
326 let directoryId = null;
327 let dirName = ""; // Wix Directory.FileSource doesn't work - https://stackoverflow.com/questions/21519388/wix-filesource-confusion
328
329 if (lastSlash > 0) {
330 // This Name attribute may also define multiple directories using the inline directory syntax.
331 // For example, "ProgramFilesFolder:\My Company\My Product\bin" would create a reference to a Directory element with Id="ProgramFilesFolder" then create directories named "My Company" then "My Product" then "bin" nested beneath each other.
332 // This syntax is a shortcut to defining each directory in an individual Directory element.
333 dirName = packagePath.substring(0, lastSlash); // https://github.com/electron-userland/electron-builder/issues/3027
334
335 directoryId = "d" + (0, _crypto().createHash)("md5").update(dirName).digest("base64").replace(/\//g, "_").replace(/\+/g, ".").replace(/=+$/, "");
336
337 if (!dirNames.has(dirName)) {
338 dirNames.add(dirName);
339 dirs.push(`<Directory Id="${directoryId}" Name="${ROOT_DIR_ID}:\\${dirName.replace(/\//g, "\\")}\\"/>`);
340 }
341 } else if (!isRootDirAddedToRemoveTable) {
342 isRootDirAddedToRemoveTable = true;
343 } // since RegistryValue can be part of Component, *** *** *** *** *** *** *** *** *** wix cannot auto generate guid
344 // https://stackoverflow.com/questions/1405100/change-my-component-guid-in-wix
345
346
347 let result = `<Component${directoryId === null ? "" : ` Directory="${directoryId}"`}>`;
348 result += `\n${fileSpace} <File Name="${fileName}" Source="$(var.appDir)${path.sep}${packagePath}" ReadOnly="yes" KeyPath="yes"`;
349 const isMainExecutable = packagePath === `${appInfo.productFilename}.exe`;
350
351 if (isMainExecutable) {
352 result += ' Id="mainExecutable"';
353 } else if (directoryId === null) {
354 result += ` Id="${path.basename(packagePath)}_f"`;
355 }
356
357 const isCreateDesktopShortcut = commonOptions.isCreateDesktopShortcut !== _CommonWindowsInstallerConfiguration().DesktopShortcutCreationPolicy.NEVER;
358
359 if (isMainExecutable && (isCreateDesktopShortcut || commonOptions.isCreateStartMenuShortcut)) {
360 result += `>\n`;
361 const shortcutName = commonOptions.shortcutName;
362
363 if (isCreateDesktopShortcut) {
364 result += `${fileSpace} <Shortcut Id="desktopShortcut" Directory="DesktopFolder" Name="${shortcutName}" WorkingDirectory="APPLICATIONFOLDER" Advertise="yes" Icon="icon.ico"/>\n`;
365 }
366
367 const hasMenuCategory = commonOptions.menuCategory != null;
368 const startMenuShortcutDirectoryId = hasMenuCategory ? "AppProgramMenuDir" : "ProgramMenuFolder";
369
370 if (commonOptions.isCreateStartMenuShortcut) {
371 if (hasMenuCategory) {
372 dirs.push(`<Directory Id="${startMenuShortcutDirectoryId}" Name="ProgramMenuFolder:\\${commonOptions.menuCategory}\\"/>`);
373 }
374
375 result += `${fileSpace} <Shortcut Id="startMenuShortcut" Directory="${startMenuShortcutDirectoryId}" Name="${shortcutName}" WorkingDirectory="APPLICATIONFOLDER" Advertise="yes" Icon="icon.ico">\n`;
376 result += `${fileSpace} <ShortcutProperty Key="System.AppUserModel.ID" Value="${_this4.packager.appInfo.id}"/>\n`;
377 result += `${fileSpace} </Shortcut>\n`;
378 }
379
380 result += `${fileSpace}</File>`;
381
382 if (hasMenuCategory) {
383 result += `<RemoveFolder Id="${startMenuShortcutDirectoryId}" On="uninstall"/>\n`;
384 }
385 } else {
386 result += `/>`;
387 }
388
389 return `${result}\n${fileSpace}</Component>`;
390 });
391 return {
392 dirs: listToString(dirs, 2),
393 files: listToString(files, 3)
394 };
395 })();
396 }
397
398}
399
400exports.default = MsiTarget;
401
402function listToString(list, indentLevel) {
403 const space = " ".repeat(indentLevel * 2);
404 return list.join(`\n${space}`);
405}
406//# sourceMappingURL=MsiTarget.js.map
\No newline at end of file