/
win32.ts
116 lines (96 loc) · 3.4 KB
/
win32.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import path from 'path';
import { sign } from '@electron/windows-sign';
import { SignOptions as WindowsInternalSignOptions } from '@electron/windows-sign/dist/esm/types';
import { App } from './platform';
import { debug, sanitizeAppName, warning } from './common';
import { ComboOptions, Options, WindowsSignOptions } from './types';
import { ExeMetadata, resedit } from './resedit';
export class WindowsApp extends App {
get originalElectronName() {
return 'electron.exe';
}
get newElectronName() {
return `${sanitizeAppName(this.executableName!)}.exe`;
}
get electronBinaryPath() {
return path.join(this.stagingPath, this.newElectronName);
}
generateReseditOptionsSansIcon(): ExeMetadata {
const win32Metadata: Options['win32metadata'] = {
FileDescription: this.opts.name,
InternalName: this.opts.name,
OriginalFilename: this.newElectronName,
ProductName: this.opts.name,
...this.opts.win32metadata,
};
return {
productVersion: this.opts.appVersion,
fileVersion: this.opts.buildVersion || this.opts.appVersion,
legalCopyright: this.opts.appCopyright,
productName: this.opts.win32metadata?.ProductName || this.opts.name,
win32Metadata,
};
}
async getIconPath() {
if (!this.opts.icon) {
return Promise.resolve();
}
return this.normalizeIconExtension('.ico');
}
needsResedit() {
return Boolean(this.opts.icon || this.opts.win32metadata || this.opts.appCopyright || this.opts.appVersion || this.opts.buildVersion || this.opts.name);
}
async runResedit() {
/* istanbul ignore if */
if (!this.needsResedit()) {
return Promise.resolve();
}
const resOpts = this.generateReseditOptionsSansIcon();
// Icon might be omitted or only exist in one OS's format, so skip it if normalizeExt reports an error
const icon = await this.getIconPath();
if (icon) {
resOpts.iconPath = icon;
}
debug(`Running resedit with the options ${JSON.stringify(resOpts)}`);
await resedit(this.electronBinaryPath, resOpts);
}
async signAppIfSpecified() {
const windowsSignOpt = this.opts.windowsSign;
const windowsMetaData = this.opts.win32metadata;
if (windowsSignOpt) {
const signOpts = createSignOpts(windowsSignOpt, windowsMetaData);
debug(`Running @electron/windows-sign with the options ${JSON.stringify(signOpts)}`);
try {
await sign(signOpts as WindowsInternalSignOptions);
} catch (err) {
// Although not signed successfully, the application is packed.
if (signOpts.continueOnError) {
warning(`Code sign failed; please retry manually. ${err}`, this.opts.quiet);
} else {
throw err;
}
}
}
}
async create() {
await this.initialize();
await this.renameElectron();
await this.copyExtraResources();
await this.runResedit();
await this.signAppIfSpecified();
return this.move();
}
}
function createSignOpts(properties: ComboOptions['windowsSign'],
windowsMetaData: ComboOptions['win32metadata']): WindowsSignOptions {
let result: WindowsSignOptions = {};
if (typeof properties === 'object') {
result = { ...properties };
}
// A little bit of convenience
if (windowsMetaData && windowsMetaData.FileDescription && !result.description) {
result.description = windowsMetaData.FileDescription;
}
return result;
}
export { WindowsApp as App };