Skip to content

Commit a18e3c6

Browse files
beyondkmpbeyondkmp
and
beyondkmp
authored
feat: Add a vendor directory option to use a custom vendor (#526)
* update nuget to v6.10.1 * add vendor directory option * delete .vscode * restore the nuget.exe * add default vendor option --------- Co-authored-by: beyondkmp <[email protected]>
1 parent 88d5b8b commit a18e3c6

File tree

3 files changed

+102
-93
lines changed

3 files changed

+102
-93
lines changed

src/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ function checkIfCommandExists(command: string): Promise<boolean> {
4545
/**
4646
* This package's main function, which creates a Squirrel.Windows executable
4747
* installer and optionally code-signs the output.
48-
*
48+
*
4949
* @param options Options for installer generation and signing
5050
* @see {@link https://github.com/Squirrel/Squirrel.Windows | Squirrel.Windows}
5151
*/
@@ -74,7 +74,7 @@ export async function createWindowsInstaller(options: SquirrelWindowsOptions): P
7474
let { appDirectory, outputDirectory, loadingGif } = options;
7575
outputDirectory = path.resolve(outputDirectory || 'installer');
7676

77-
const vendorPath = path.join(__dirname, '..', 'vendor');
77+
const vendorPath = options.vendorDirectory || path.join(__dirname, '..', 'vendor');
7878
const vendorUpdate = path.join(vendorPath, 'Squirrel.exe');
7979
const appUpdate = path.join(appDirectory, 'Squirrel.exe');
8080

src/options.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ export interface SquirrelWindowsOptions {
99
* The folder path of your Electron app
1010
*/
1111
appDirectory: string;
12+
/**
13+
* The folder path of Squirrel windows
14+
*/
15+
vendorDirectory?: string;
1216
/**
1317
* The folder path to create the .exe installer in.
1418
*
@@ -23,7 +27,7 @@ export interface SquirrelWindowsOptions {
2327
nuspecTemplate?: string;
2428
/**
2529
* The local path to a `.gif` file to display during install.
26-
*
30+
*
2731
* @defaultValue the bundled {@link https://github.com/electron/windows-installer/blob/main/resources/install-spinner.gif | install-spinner.gif}
2832
*/
2933
loadingGif?: string;
@@ -92,7 +96,7 @@ export interface SquirrelWindowsOptions {
9296
name?: string;
9397
/**
9498
* The path to an Authenticode Code Signing Certificate.
95-
*
99+
*
96100
* This is a legacy parameter provided for backwards compatibility.
97101
* For more comprehensive support of various codesigning scenarios
98102
* like EV certificates, see the
@@ -101,7 +105,7 @@ export interface SquirrelWindowsOptions {
101105
certificateFile?: string;
102106
/**
103107
* The password to decrypt the certificate given in `certificateFile`
104-
*
108+
*
105109
* This is a legacy parameter provided for backwards compatibility.
106110
* For more comprehensive support of various codesigning scenarios
107111
* like EV certificates, see the
@@ -113,7 +117,7 @@ export interface SquirrelWindowsOptions {
113117
*
114118
* Overrides {@link SquirrelWindowsOptions.certificateFile | certificateFile}
115119
* and {@link SquirrelWindowsOptions.certificatePassword | certificatePassword}`.
116-
*
120+
*
117121
* This is a legacy parameter provided for backwards compatibility.
118122
* For more comprehensive support of various codesigning scenarios
119123
* like EV certificates, see the
@@ -186,13 +190,13 @@ export interface SquirrelWindowsOptions {
186190

187191
/**
188192
* Requires Node.js 18 or newer.
189-
*
193+
*
190194
* Sign your app with `@electron/windows-sign`, allowing for full customization
191195
* of the code-signing process - and supports more complicated scenarios like
192196
* cloud-hosted EV certificates, custom sign pipelines, and per-file overrides.
193197
* It also supports all existing "simple" codesigning scenarios, including
194-
* just passing a certificate file and password.
195-
*
198+
* just passing a certificate file and password.
199+
*
196200
* @see {@link https://github.com/electron/windows-sign | @electron/windows-sign documentation}
197201
* for all possible configuration options.
198202
*/

src/sign.ts

+89-84
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,89 @@
1-
import type { createSeaSignTool as createSeaSignToolType } from '@electron/windows-sign';
2-
import path from 'path';
3-
import semver from 'semver';
4-
import fs from 'fs-extra';
5-
6-
import { SquirrelWindowsOptions } from './options';
7-
8-
const VENDOR_PATH = path.join(__dirname, '..', 'vendor');
9-
const ORIGINAL_SIGN_TOOL_PATH = path.join(VENDOR_PATH, 'signtool.exe');
10-
const BACKUP_SIGN_TOOL_PATH = path.join(VENDOR_PATH, 'signtool-original.exe');
11-
const SIGN_LOG_PATH = path.join(VENDOR_PATH, 'electron-windows-sign.log');
12-
13-
/**
14-
* This method uses @electron/windows-sign to create a fake signtool.exe
15-
* that can be called by Squirrel - but then just calls @electron/windows-sign
16-
* to actually perform the signing.
17-
*
18-
* That's useful for users who need a high degree of customization of the signing
19-
* process but still want to use @electron/windows-installer.
20-
*/
21-
export async function createSignTool(options: SquirrelWindowsOptions): Promise<void> {
22-
if (!options.windowsSign) {
23-
throw new Error('Signtool should only be created if windowsSign options are set');
24-
}
25-
26-
const createSeaSignTool = await getCreateSeaSignTool();
27-
28-
await resetSignTool();
29-
await fs.remove(SIGN_LOG_PATH);
30-
31-
// Make a backup of signtool.exe
32-
await fs.copy(ORIGINAL_SIGN_TOOL_PATH, BACKUP_SIGN_TOOL_PATH, { overwrite: true });
33-
34-
// Create a new signtool.exe using @electron/windows-sign
35-
await createSeaSignTool({
36-
path: ORIGINAL_SIGN_TOOL_PATH,
37-
windowsSign: options.windowsSign
38-
});
39-
}
40-
41-
/**
42-
* Ensure that signtool.exe is actually the "real" signtool.exe, not our
43-
* fake substitute.
44-
*/
45-
export async function resetSignTool() {
46-
if (fs.existsSync(BACKUP_SIGN_TOOL_PATH)) {
47-
// Reset the backup of signtool.exe
48-
await fs.copy(BACKUP_SIGN_TOOL_PATH, ORIGINAL_SIGN_TOOL_PATH, { overwrite: true });
49-
await fs.remove(BACKUP_SIGN_TOOL_PATH);
50-
}
51-
}
52-
53-
/**
54-
* @electron/windows-installer only requires Node.js >= 8.0.0.
55-
* @electron/windows-sign requires Node.js >= 16.0.0.
56-
* @electron/windows-sign's "fake signtool.exe" feature requires
57-
* Node.js >= 20.0.0, the first version to contain the "single
58-
* executable" feature with proper support.
59-
*
60-
* Since this is overall a very niche feature and only benefits
61-
* consumers with rather advanced codesigning needs, we did not
62-
* want to make Node.js v18 a hard requirement for @electron/windows-installer.
63-
*
64-
* Instead, @electron/windows-sign is an optional dependency - and
65-
* if it didn't install, we'll throw a useful error here.
66-
*
67-
* @returns
68-
*/
69-
async function getCreateSeaSignTool(): Promise<typeof createSeaSignToolType> {
70-
try {
71-
const { createSeaSignTool } = await import('@electron/windows-sign');
72-
return createSeaSignTool;
73-
} catch(error) {
74-
let message = 'In order to use windowsSign options, @electron/windows-sign must be installed as a dependency.';
75-
76-
if (semver.lte(process.version, '20.0.0')) {
77-
message += ` You are currently using Node.js ${process.version}. Please upgrade to Node.js 19 or later and reinstall all dependencies to ensure that @electron/windows-sign is available.`;
78-
} else {
79-
message += ` ${error}`;
80-
}
81-
82-
throw new Error(message);
83-
}
84-
}
1+
import type { createSeaSignTool as createSeaSignToolType } from '@electron/windows-sign';
2+
import path from 'path';
3+
import semver from 'semver';
4+
import fs from 'fs-extra';
5+
6+
import { SquirrelWindowsOptions } from './options';
7+
8+
let VENDOR_PATH: string;
9+
let ORIGINAL_SIGN_TOOL_PATH: string;
10+
let BACKUP_SIGN_TOOL_PATH: string;
11+
let SIGN_LOG_PATH: string;
12+
13+
/**
14+
* This method uses @electron/windows-sign to create a fake signtool.exe
15+
* that can be called by Squirrel - but then just calls @electron/windows-sign
16+
* to actually perform the signing.
17+
*
18+
* That's useful for users who need a high degree of customization of the signing
19+
* process but still want to use @electron/windows-installer.
20+
*/
21+
export async function createSignTool(options: SquirrelWindowsOptions): Promise<void> {
22+
if (!options.windowsSign) {
23+
throw new Error('Signtool should only be created if windowsSign options are set');
24+
}
25+
26+
VENDOR_PATH = options.vendorDirectory || path.join(__dirname, '..', 'vendor');
27+
ORIGINAL_SIGN_TOOL_PATH = path.join(VENDOR_PATH, 'signtool.exe');
28+
BACKUP_SIGN_TOOL_PATH = path.join(VENDOR_PATH, 'signtool-original.exe');
29+
SIGN_LOG_PATH = path.join(VENDOR_PATH, 'electron-windows-sign.log');
30+
31+
const createSeaSignTool = await getCreateSeaSignTool();
32+
33+
await resetSignTool();
34+
await fs.remove(SIGN_LOG_PATH);
35+
36+
// Make a backup of signtool.exe
37+
await fs.copy(ORIGINAL_SIGN_TOOL_PATH, BACKUP_SIGN_TOOL_PATH, { overwrite: true });
38+
39+
// Create a new signtool.exe using @electron/windows-sign
40+
await createSeaSignTool({
41+
path: ORIGINAL_SIGN_TOOL_PATH,
42+
windowsSign: options.windowsSign
43+
});
44+
}
45+
46+
/**
47+
* Ensure that signtool.exe is actually the "real" signtool.exe, not our
48+
* fake substitute.
49+
*/
50+
export async function resetSignTool() {
51+
if (fs.existsSync(BACKUP_SIGN_TOOL_PATH)) {
52+
// Reset the backup of signtool.exe
53+
await fs.copy(BACKUP_SIGN_TOOL_PATH, ORIGINAL_SIGN_TOOL_PATH, { overwrite: true });
54+
await fs.remove(BACKUP_SIGN_TOOL_PATH);
55+
}
56+
}
57+
58+
/**
59+
* @electron/windows-installer only requires Node.js >= 8.0.0.
60+
* @electron/windows-sign requires Node.js >= 16.0.0.
61+
* @electron/windows-sign's "fake signtool.exe" feature requires
62+
* Node.js >= 20.0.0, the first version to contain the "single
63+
* executable" feature with proper support.
64+
*
65+
* Since this is overall a very niche feature and only benefits
66+
* consumers with rather advanced codesigning needs, we did not
67+
* want to make Node.js v18 a hard requirement for @electron/windows-installer.
68+
*
69+
* Instead, @electron/windows-sign is an optional dependency - and
70+
* if it didn't install, we'll throw a useful error here.
71+
*
72+
* @returns
73+
*/
74+
async function getCreateSeaSignTool(): Promise<typeof createSeaSignToolType> {
75+
try {
76+
const { createSeaSignTool } = await import('@electron/windows-sign');
77+
return createSeaSignTool;
78+
} catch(error) {
79+
let message = 'In order to use windowsSign options, @electron/windows-sign must be installed as a dependency.';
80+
81+
if (semver.lte(process.version, '20.0.0')) {
82+
message += ` You are currently using Node.js ${process.version}. Please upgrade to Node.js 19 or later and reinstall all dependencies to ensure that @electron/windows-sign is available.`;
83+
} else {
84+
message += ` ${error}`;
85+
}
86+
87+
throw new Error(message);
88+
}
89+
}

0 commit comments

Comments
 (0)