-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
fix: generate stubExecutableExe and sign it #8959
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
beyondkmp
merged 40 commits into
electron-userland:master
from
beyondkmp:StubExecutable
Jul 31, 2025
Merged
Changes from all commits
Commits
Show all changes
40 commits
Select commit
Hold shift + click to select a range
15ee162
generate stubExecutableExe and sign it
beyondkmp 3e7b26b
generate _ExecutionStub.exe after prepared vendor
beyondkmp 1134394
add vendor files from winows-installer
beyondkmp c5c41f5
update squirrel window from https://github.com/beyondkmp/Squirrel.Win…
beyondkmp bcabba8
change default vendor
beyondkmp faa8df7
update vendor from https://github.com/beyondkmp/Squirrel.Windows/acti…
beyondkmp d5bdf42
fix ut
beyondkmp aea79ff
update ut
beyondkmp 03e9201
update ut
beyondkmp f3f25c1
change to default vendor when custom vendor is empty
beyondkmp 5d29591
Merge branch 'master' into StubExecutable
mmaietta 49a88b7
fix comments
beyondkmp dc6c1fb
Merge branch 'master' into StubExecutable
beyondkmp ecfa950
add vendor to package.json
beyondkmp b954be0
fix comments
beyondkmp 9800401
fix fileNameWithoutExt with basename .exe
beyondkmp 4c7599d
Merge branch 'master' into StubExecutable
beyondkmp a5733ba
Merge branch 'master' into StubExecutable
beyondkmp 713d4f3
refactor: update Squirrel.Windows vendor handling and remove obsolete…
beyondkmp 1825476
Merge branch 'master' into StubExecutable
beyondkmp 73db025
chore: remove vendor directory from package.json files list to stream…
beyondkmp b7b1b58
chore: update Squirrel.Windows binary version to 2.0.1-patched for im…
beyondkmp 0e5b61c
chore: update Squirrel.Windows binary download method to use new URL …
beyondkmp 3b9ba8e
fix: update vendor directory resolution for Squirrel.Windows to ensur…
beyondkmp 4d18d74
fix: correct path for copying custom Squirrel.Windows binaries to ens…
beyondkmp 634c84c
Merge branch 'master' into StubExecutable
beyondkmp 3dd31a0
Merge branch 'master' into StubExecutable
mmaietta 439c4ce
Merge branch 'master' into StubExecutable
mmaietta 1cd2bc9
fix comments
beyondkmp e78f7dd
refactor: improve error handling for missing app executable in Squirr…
beyondkmp 69feef9
Merge branch 'master' into StubExecutable
mmaietta 71ee208
Create lovely-brooms-move.md
mmaietta a08d1db
Merge branch 'master' into StubExecutable
beyondkmp 390f631
refactor(SquirrelWindowsTarget): replace getBin with getBinFromUrl fo…
beyondkmp eb5d7b3
use getbin
beyondkmp f92b073
Merge branch 'master' into StubExecutable
mmaietta 3ad8b8a
fix ut
beyondkmp 2b86c16
Merge branch 'master' into StubExecutable
beyondkmp 07badb5
delete log
beyondkmp afa0513
Merge branch 'master' into StubExecutable
beyondkmp File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "electron-builder-squirrel-windows": patch | ||
| --- | ||
|
|
||
| fix: generate stubExecutableExe and sign it for squirrel.windows using new electron-builder-binaries asset |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,6 @@ | ||
| import { InvalidConfigurationError, log, isEmptyOrSpaces } from "builder-util" | ||
| import { execWine } from "app-builder-lib/out/wine" | ||
| import { getBinFromUrl } from "app-builder-lib/out/binDownload" | ||
| import { sanitizeFileName } from "builder-util/out/filename" | ||
| import { Arch, getArchSuffix, SquirrelWindowsOptions, Target, WinPackager } from "app-builder-lib" | ||
| import * as path from "path" | ||
|
|
@@ -20,31 +22,56 @@ export default class SquirrelWindowsTarget extends Target { | |
| } | ||
|
|
||
| private async prepareSignedVendorDirectory(): Promise<string> { | ||
| // If not specified will use the Squirrel.Windows that is shipped with electron-installer(https://github.com/electron/windows-installer/tree/main/vendor) | ||
| // After https://github.com/electron-userland/electron-builder-binaries/pull/56 merged, will add `electron-builder-binaries` to get the latest version of squirrel. | ||
| let vendorDirectory = this.options.customSquirrelVendorDir || path.join(require.resolve("electron-winstaller/package.json"), "..", "vendor") | ||
| if (isEmptyOrSpaces(vendorDirectory) || !fs.existsSync(vendorDirectory)) { | ||
| log.warn({ vendorDirectory }, "unable to access Squirrel.Windows vendor directory, falling back to default electron-winstaller") | ||
| vendorDirectory = path.join(require.resolve("electron-winstaller/package.json"), "..", "vendor") | ||
| } | ||
|
|
||
| const customSquirrelVendorDirectory = this.options.customSquirrelVendorDir | ||
| const tmpVendorDirectory = await this.packager.info.tempDirManager.createTempDir({ prefix: "squirrel-windows-vendor" }) | ||
| // Copy entire vendor directory to temp directory | ||
| await fs.promises.cp(vendorDirectory, tmpVendorDirectory, { recursive: true }) | ||
| log.debug({ from: vendorDirectory, to: tmpVendorDirectory }, "copied vendor directory") | ||
|
|
||
| const files = await fs.promises.readdir(tmpVendorDirectory) | ||
| for (const file of files) { | ||
| if (["Squirrel.exe", "StubExecutable.exe"].includes(file)) { | ||
| const filePath = path.join(tmpVendorDirectory, file) | ||
| log.debug({ file: filePath }, "signing vendor executable") | ||
| await this.packager.sign(filePath) | ||
| } | ||
| if (isEmptyOrSpaces(customSquirrelVendorDirectory) || !fs.existsSync(customSquirrelVendorDirectory)) { | ||
| log.warn({ customSquirrelVendorDirectory: customSquirrelVendorDirectory }, "unable to access custom Squirrel.Windows vendor directory, falling back to default vendor ") | ||
| const windowInstallerPackage = require.resolve("electron-winstaller/package.json") | ||
| const vendorDirectory = path.join(path.dirname(windowInstallerPackage), "vendor") | ||
|
|
||
| const squirrelBin = await getBinFromUrl( | ||
| "[email protected]", | ||
| "squirrel.windows-2.0.1-patched.7z", | ||
| "DWijIRRElidu/Rq0yegAKqo2g6aVJUPvcRyvkzUoBPbRasIk61P6xY2fBMdXw6wT17md7NzrTI9/zA1wT9vEqg==" | ||
mmaietta marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ) | ||
|
|
||
| await fs.promises.cp(vendorDirectory, tmpVendorDirectory, { recursive: true }) | ||
| // copy the patched squirrel to tmp vendor directory | ||
| await fs.promises.cp(path.join(squirrelBin, "electron-winstaller", "vendor"), tmpVendorDirectory, { recursive: true }) | ||
| } else { | ||
| // copy the custom squirrel vendor directory to tmp vendor directory | ||
| await fs.promises.cp(customSquirrelVendorDirectory, tmpVendorDirectory, { recursive: true }) | ||
| } | ||
|
|
||
| const files = await fs.promises.readdir(tmpVendorDirectory) | ||
| const squirrelExe = files.find(f => f === "Squirrel.exe") | ||
| if (squirrelExe) { | ||
| const filePath = path.join(tmpVendorDirectory, squirrelExe) | ||
| log.debug({ file: filePath }, "signing vendor executable") | ||
| await this.packager.sign(filePath) | ||
| } else { | ||
| log.warn("Squirrel.exe not found in vendor directory, skipping signing") | ||
| } | ||
mmaietta marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return tmpVendorDirectory | ||
| } | ||
|
|
||
| private async generateStubExecutableExe(appOutDir: string, vendorDir: string) { | ||
| const files = await fs.promises.readdir(appOutDir, { withFileTypes: true }) | ||
| const appExe = files.find(f => f.name === `${this.exeName}.exe`) | ||
| if (!appExe) { | ||
| throw new Error(`App executable not found in app directory: ${appOutDir}`) | ||
| } | ||
|
|
||
| const filePath = path.join(appOutDir, appExe.name) | ||
| const stubExePath = path.join(appOutDir, `${this.exeName}_ExecutionStub.exe`) | ||
| await fs.promises.copyFile(path.join(vendorDir, "StubExecutable.exe"), stubExePath) | ||
| await execWine(path.join(vendorDir, "WriteZipToSetup.exe"), null, ["--copy-stub-resources", filePath, stubExePath]) | ||
| await this.packager.sign(stubExePath) | ||
| log.debug({ file: filePath }, "signing app executable") | ||
| await this.packager.sign(filePath) | ||
| } | ||
mmaietta marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| async build(appOutDir: string, arch: Arch) { | ||
| const packager = this.packager | ||
| const version = packager.appInfo.version | ||
|
|
@@ -62,6 +89,7 @@ export default class SquirrelWindowsTarget extends Target { | |
| arch, | ||
| }) | ||
| const distOptions = await this.computeEffectiveDistOptions(appOutDir, installerOutDir, setupFile) | ||
| await this.generateStubExecutableExe(appOutDir, distOptions.vendorDirectory!) | ||
| await createWindowsInstaller(distOptions) | ||
|
|
||
| await packager.signAndEditResources(artifactPath, arch, installerOutDir) | ||
|
|
@@ -120,6 +148,10 @@ export default class SquirrelWindowsTarget extends Target { | |
| return this.options.name || this.packager.appInfo.name | ||
| } | ||
|
|
||
| private get exeName() { | ||
| return this.packager.appInfo.productFilename || this.options.name || this.packager.appInfo.productName | ||
| } | ||
|
|
||
| private select7zipArch(vendorDirectory: string) { | ||
| // https://github.com/electron/windows-installer/blob/main/script/select-7z-arch.js | ||
| // Even if we're cross-compiling for a different arch like arm64, | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.