From 7e9cdb9d9c8c38f919da184142c8bb04e9bf88cf Mon Sep 17 00:00:00 2001 From: Maria Date: Tue, 6 Jun 2017 00:07:06 +0300 Subject: [PATCH 1/4] fix: Do not pack "elevate.exe" when not needed Close #1620 --- packages/electron-builder/src/targets/nsis.ts | 11 +++++++---- test/src/helpers/winHelper.ts | 9 ++++++++- test/src/windows/oneClickInstallerTest.ts | 3 ++- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/packages/electron-builder/src/targets/nsis.ts b/packages/electron-builder/src/targets/nsis.ts index 111e78b1069..501a0d853f1 100644 --- a/packages/electron-builder/src/targets/nsis.ts +++ b/packages/electron-builder/src/targets/nsis.ts @@ -106,10 +106,13 @@ export class NsisTarget extends Target { /** @private */ async buildAppPackage(appOutDir: string, arch: Arch) { - await BluebirdPromise.all([ - copyFile(path.join(await nsisPathPromise, "elevate.exe"), path.join(appOutDir, "resources", "elevate.exe"), null, false), - copyFile(path.join(await getSignVendorPath(), "windows-10", Arch[arch], "signtool.exe"), path.join(appOutDir, "resources", "signtool.exe"), null, false), - ]) + var filesToCopy = []; + if (this.options.allowElevation === undefined || this.options.allowElevation) { + filesToCopy.push(copyFile(path.join(await nsisPathPromise, "elevate.exe"), path.join(appOutDir, "resources", "elevate.exe"), null, false)); + } + filesToCopy.push(copyFile(path.join(await getSignVendorPath(), "windows-10", Arch[arch], "signtool.exe"), path.join(appOutDir, "resources", "signtool.exe"), null, false)); + + await BluebirdPromise.all(filesToCopy) const packager = this.packager const format = this.options.useZip ? "zip" : "7z" diff --git a/test/src/helpers/winHelper.ts b/test/src/helpers/winHelper.ts index 55ca82a69f5..f8c90b25af7 100644 --- a/test/src/helpers/winHelper.ts +++ b/test/src/helpers/winHelper.ts @@ -9,8 +9,15 @@ import { assertThat } from "./fileAssert" import { PackedContext } from "./packTester" import { diff, WineManager } from "./wine" -export async function expectUpdateMetadata(context: PackedContext, arch: Arch = Arch.ia32, requireCodeSign: boolean = false): Promise { +export async function expectUpdateMetadata(context: PackedContext, arch: Arch = Arch.ia32, requireCodeSign: boolean = false, allowElevation: boolean = true): Promise { const data = safeLoad(await readFile(path.join(context.getResources(Platform.WINDOWS, arch), "app-update.yml"), "utf-8")) + + if (allowElevation) { + await assertThat(path.join(context.getResources(Platform.WINDOWS, arch), "elevate.exe")).isFile() + } else { + await assertThat(path.join(context.getResources(Platform.WINDOWS, arch), "elevate.exe")).doesNotExist() + } + if (requireCodeSign && process.env.CSC_KEY_PASSWORD != null) { expect(data.publisherName).toEqual(["Developer ID Installer: Vladimir Krivosheev (X8C9Z9L4HW)"]) delete data.publisherName diff --git a/test/src/windows/oneClickInstallerTest.ts b/test/src/windows/oneClickInstallerTest.ts index 3e26bcaa655..6e81b226849 100644 --- a/test/src/windows/oneClickInstallerTest.ts +++ b/test/src/windows/oneClickInstallerTest.ts @@ -19,13 +19,14 @@ test("one-click", app({ }, nsis: { deleteAppDataOnUninstall: true, + allowElevation: false }, } }, { signed: true, packed: async (context) => { await doTest(context.outDir, true) - await expectUpdateMetadata(context, Arch.ia32, true) + await expectUpdateMetadata(context, Arch.ia32, true, false) } })) From 573120f2ccc7148f7dc771da1cc75e7478e56919 Mon Sep 17 00:00:00 2001 From: Maria Date: Thu, 8 Jun 2017 14:33:24 +0300 Subject: [PATCH 2/4] Remove the assisting files after installation --- docs/Options.md | 1 + .../src/options/winOptions.ts | 6 +++++ packages/electron-builder/src/targets/nsis.ts | 15 +++++++------ .../templates/nsis/installSection.nsh | 5 +++++ .../oneClickInstallerTest.js.snap | 6 +++++ test/src/helpers/winHelper.ts | 8 +------ test/src/windows/oneClickInstallerTest.ts | 22 +++++++++++++++++-- 7 files changed, 47 insertions(+), 16 deletions(-) diff --git a/docs/Options.md b/docs/Options.md index e692990e608..70f6545b497 100644 --- a/docs/Options.md +++ b/docs/Options.md @@ -438,6 +438,7 @@ See [NSIS target notes](https://github.com/electron-userland/electron-builder/wi | artifactName| string \| null | The [artifact file name pattern](https://github.com/electron-userland/electron-builder/wiki/Options#artifact-file-name-pattern). Defaults to `${productName} Setup ${version}.${ext}`. | | unicode = true| boolean | Whether to create [Unicode installer](http://nsis.sourceforge.net/Docs/Chapter1.html#intro-unicode). | | deleteAppDataOnUninstall| boolean | *one-click installer only.* Whether to delete app data on uninstall. | +| deleteSupportingFilesAfterInstall = false| boolean | Whether to delete the files that are packed to support the installation. | diff --git a/packages/electron-builder/src/options/winOptions.ts b/packages/electron-builder/src/options/winOptions.ts index e277d516dea..fa395436db7 100644 --- a/packages/electron-builder/src/options/winOptions.ts +++ b/packages/electron-builder/src/options/winOptions.ts @@ -224,6 +224,12 @@ export interface NsisOptions extends CommonNsisOptions, TargetSpecificOptions { * @default false */ readonly deleteAppDataOnUninstall?: boolean + + /** + * Whether to delete the files that are packed to support the installation. + * @default false + */ + readonly deleteSupportingFilesAfterInstall?: boolean } /** diff --git a/packages/electron-builder/src/targets/nsis.ts b/packages/electron-builder/src/targets/nsis.ts index 501a0d853f1..be425fe0e73 100644 --- a/packages/electron-builder/src/targets/nsis.ts +++ b/packages/electron-builder/src/targets/nsis.ts @@ -106,13 +106,10 @@ export class NsisTarget extends Target { /** @private */ async buildAppPackage(appOutDir: string, arch: Arch) { - var filesToCopy = []; - if (this.options.allowElevation === undefined || this.options.allowElevation) { - filesToCopy.push(copyFile(path.join(await nsisPathPromise, "elevate.exe"), path.join(appOutDir, "resources", "elevate.exe"), null, false)); - } - filesToCopy.push(copyFile(path.join(await getSignVendorPath(), "windows-10", Arch[arch], "signtool.exe"), path.join(appOutDir, "resources", "signtool.exe"), null, false)); - - await BluebirdPromise.all(filesToCopy) + await BluebirdPromise.all([ + copyFile(path.join(await nsisPathPromise, "elevate.exe"), path.join(appOutDir, "resources", "elevate.exe"), null, false), + copyFile(path.join(await getSignVendorPath(), "windows-10", Arch[arch], "signtool.exe"), path.join(appOutDir, "resources", "signtool.exe"), null, false), + ]) const packager = this.packager const format = this.options.useZip ? "zip" : "7z" @@ -368,6 +365,10 @@ export class NsisTarget extends Target { defines.UNINSTALLER_ICON = uninstallerIcon defines.MUI_UNICON = uninstallerIcon } + + if (options.deleteSupportingFilesAfterInstall) { + defines.DELETE_SUPPORTING_FILES_AFTER_INSTALL = null + } } private configureDefinesForAllTypeOfInstaller(defines: any) { diff --git a/packages/electron-builder/templates/nsis/installSection.nsh b/packages/electron-builder/templates/nsis/installSection.nsh index 25c1c72ce5b..767c344dabc 100644 --- a/packages/electron-builder/templates/nsis/installSection.nsh +++ b/packages/electron-builder/templates/nsis/installSection.nsh @@ -196,6 +196,11 @@ WinShell::SetLnkAUMI "$desktopLink" "${APP_ID}" !insertmacro customInstall !endif +!ifdef DELETE_SUPPORTING_FILES_AFTER_INSTALL + Delete $INSTDIR\resources\elevate.exe + Delete $INSTDIR\resources\signtool.exe +!endif + !ifdef ONE_CLICK !ifdef RUN_AFTER_FINISH ${IfNot} ${Silent} diff --git a/test/out/windows/__snapshots__/oneClickInstallerTest.js.snap b/test/out/windows/__snapshots__/oneClickInstallerTest.js.snap index e077eaed612..2ce849e7e13 100644 --- a/test/out/windows/__snapshots__/oneClickInstallerTest.js.snap +++ b/test/out/windows/__snapshots__/oneClickInstallerTest.js.snap @@ -24,6 +24,12 @@ Object { } `; +exports[`delete supporting files after install 1`] = ` +Object { + "win": Array [], +} +`; + exports[`file associations only perMachine 1`] = `"Please set perMachine to true — file associations works on Windows only if installed for all users"`; exports[`installerHeaderIcon 1`] = ` diff --git a/test/src/helpers/winHelper.ts b/test/src/helpers/winHelper.ts index f8c90b25af7..7c02f9a34d3 100644 --- a/test/src/helpers/winHelper.ts +++ b/test/src/helpers/winHelper.ts @@ -9,15 +9,9 @@ import { assertThat } from "./fileAssert" import { PackedContext } from "./packTester" import { diff, WineManager } from "./wine" -export async function expectUpdateMetadata(context: PackedContext, arch: Arch = Arch.ia32, requireCodeSign: boolean = false, allowElevation: boolean = true): Promise { +export async function expectUpdateMetadata(context: PackedContext, arch: Arch = Arch.ia32, requireCodeSign: boolean = false): Promise { const data = safeLoad(await readFile(path.join(context.getResources(Platform.WINDOWS, arch), "app-update.yml"), "utf-8")) - if (allowElevation) { - await assertThat(path.join(context.getResources(Platform.WINDOWS, arch), "elevate.exe")).isFile() - } else { - await assertThat(path.join(context.getResources(Platform.WINDOWS, arch), "elevate.exe")).doesNotExist() - } - if (requireCodeSign && process.env.CSC_KEY_PASSWORD != null) { expect(data.publisherName).toEqual(["Developer ID Installer: Vladimir Krivosheev (X8C9Z9L4HW)"]) delete data.publisherName diff --git a/test/src/windows/oneClickInstallerTest.ts b/test/src/windows/oneClickInstallerTest.ts index 6e81b226849..2cdce3c02e5 100644 --- a/test/src/windows/oneClickInstallerTest.ts +++ b/test/src/windows/oneClickInstallerTest.ts @@ -18,9 +18,13 @@ test("one-click", app({ package: "TestApp", }, nsis: { - deleteAppDataOnUninstall: true, - allowElevation: false + deleteAppDataOnUninstall: true }, + }, + effectiveOptionComputed: async (it) => { + const defines = it[0] + expect(defines.DELETE_SUPPORTING_FILES_AFTER_INSTALL).not.toBeDefined() + return false } }, { signed: true, @@ -207,4 +211,18 @@ test.ifAll.ifNotCiMac("web installer (default github)", app({ delete data.sha512 expect(data).toMatchSnapshot() }, +})) + +test("delete supporting files after install", app({ + targets: nsisTarget, + config: { + nsis: { + deleteSupportingFilesAfterInstall: true + } + }, + effectiveOptionComputed: async (it) => { + const defines = it[0] + expect(defines.DELETE_SUPPORTING_FILES_AFTER_INSTALL).toBeDefined() + return true + } })) \ No newline at end of file From d5d10cb6a260d2937f72e458393778e124f2d805 Mon Sep 17 00:00:00 2001 From: Maria Date: Thu, 8 Jun 2017 16:15:31 +0300 Subject: [PATCH 3/4] Define and use doNotPackElevateHelper nsis option Revert the changes for the installer. Don't pack the signtool.exe at all. --- docs/Options.md | 2 +- .../src/options/winOptions.ts | 4 +-- packages/electron-builder/src/targets/nsis.ts | 12 +++------ .../templates/nsis/installSection.nsh | 5 ---- .../oneClickInstallerTest.js.snap | 6 ----- test/src/helpers/winHelper.ts | 8 +++++- test/src/windows/oneClickInstallerTest.ts | 26 +++---------------- 7 files changed, 17 insertions(+), 46 deletions(-) diff --git a/docs/Options.md b/docs/Options.md index 70f6545b497..4d40d8dfbfc 100644 --- a/docs/Options.md +++ b/docs/Options.md @@ -438,7 +438,7 @@ See [NSIS target notes](https://github.com/electron-userland/electron-builder/wi | artifactName| string \| null | The [artifact file name pattern](https://github.com/electron-userland/electron-builder/wiki/Options#artifact-file-name-pattern). Defaults to `${productName} Setup ${version}.${ext}`. | | unicode = true| boolean | Whether to create [Unicode installer](http://nsis.sourceforge.net/Docs/Chapter1.html#intro-unicode). | | deleteAppDataOnUninstall| boolean | *one-click installer only.* Whether to delete app data on uninstall. | -| deleteSupportingFilesAfterInstall = false| boolean | Whether to delete the files that are packed to support the installation. | +| doNotPackElevateHelper = false| boolean | Whether to pack the elevate executable. | diff --git a/packages/electron-builder/src/options/winOptions.ts b/packages/electron-builder/src/options/winOptions.ts index fa395436db7..61d2343aa26 100644 --- a/packages/electron-builder/src/options/winOptions.ts +++ b/packages/electron-builder/src/options/winOptions.ts @@ -226,10 +226,10 @@ export interface NsisOptions extends CommonNsisOptions, TargetSpecificOptions { readonly deleteAppDataOnUninstall?: boolean /** - * Whether to delete the files that are packed to support the installation. + * Whether to pack the elevate executable * @default false */ - readonly deleteSupportingFilesAfterInstall?: boolean + readonly doNotPackElevateHelper?: boolean } /** diff --git a/packages/electron-builder/src/targets/nsis.ts b/packages/electron-builder/src/targets/nsis.ts index be425fe0e73..b8d0fb02a0d 100644 --- a/packages/electron-builder/src/targets/nsis.ts +++ b/packages/electron-builder/src/targets/nsis.ts @@ -13,7 +13,6 @@ import sanitizeFileName from "sanitize-filename" import { v5 as uuid5 } from "uuid-1345" import { NsisOptions, PortableOptions } from "../options/winOptions" import { normalizeExt } from "../platformPackager" -import { getSignVendorPath } from "../windowsCodeSign" import { WinPackager } from "../winPackager" import { archive } from "./archive" import { bundledLanguages, getLicenseFiles, lcid, toLangWithRegion } from "./license" @@ -106,10 +105,9 @@ export class NsisTarget extends Target { /** @private */ async buildAppPackage(appOutDir: string, arch: Arch) { - await BluebirdPromise.all([ - copyFile(path.join(await nsisPathPromise, "elevate.exe"), path.join(appOutDir, "resources", "elevate.exe"), null, false), - copyFile(path.join(await getSignVendorPath(), "windows-10", Arch[arch], "signtool.exe"), path.join(appOutDir, "resources", "signtool.exe"), null, false), - ]) + if (this.options.doNotPackElevateHelper !== true) { + await copyFile(path.join(await nsisPathPromise, "elevate.exe"), path.join(appOutDir, "resources", "elevate.exe"), null, false) + } const packager = this.packager const format = this.options.useZip ? "zip" : "7z" @@ -365,10 +363,6 @@ export class NsisTarget extends Target { defines.UNINSTALLER_ICON = uninstallerIcon defines.MUI_UNICON = uninstallerIcon } - - if (options.deleteSupportingFilesAfterInstall) { - defines.DELETE_SUPPORTING_FILES_AFTER_INSTALL = null - } } private configureDefinesForAllTypeOfInstaller(defines: any) { diff --git a/packages/electron-builder/templates/nsis/installSection.nsh b/packages/electron-builder/templates/nsis/installSection.nsh index 767c344dabc..25c1c72ce5b 100644 --- a/packages/electron-builder/templates/nsis/installSection.nsh +++ b/packages/electron-builder/templates/nsis/installSection.nsh @@ -196,11 +196,6 @@ WinShell::SetLnkAUMI "$desktopLink" "${APP_ID}" !insertmacro customInstall !endif -!ifdef DELETE_SUPPORTING_FILES_AFTER_INSTALL - Delete $INSTDIR\resources\elevate.exe - Delete $INSTDIR\resources\signtool.exe -!endif - !ifdef ONE_CLICK !ifdef RUN_AFTER_FINISH ${IfNot} ${Silent} diff --git a/test/out/windows/__snapshots__/oneClickInstallerTest.js.snap b/test/out/windows/__snapshots__/oneClickInstallerTest.js.snap index 2ce849e7e13..e077eaed612 100644 --- a/test/out/windows/__snapshots__/oneClickInstallerTest.js.snap +++ b/test/out/windows/__snapshots__/oneClickInstallerTest.js.snap @@ -24,12 +24,6 @@ Object { } `; -exports[`delete supporting files after install 1`] = ` -Object { - "win": Array [], -} -`; - exports[`file associations only perMachine 1`] = `"Please set perMachine to true — file associations works on Windows only if installed for all users"`; exports[`installerHeaderIcon 1`] = ` diff --git a/test/src/helpers/winHelper.ts b/test/src/helpers/winHelper.ts index 7c02f9a34d3..fb1930b07ec 100644 --- a/test/src/helpers/winHelper.ts +++ b/test/src/helpers/winHelper.ts @@ -20,7 +20,7 @@ export async function expectUpdateMetadata(context: PackedContext, arch: Arch = expect(data).toMatchSnapshot() } -export async function doTest(outDir: string, perUser: boolean, productFilename = "TestApp Setup", name = "TestApp", menuCategory: string | null = null) { +export async function doTest(outDir: string, perUser: boolean, productFilename = "TestApp Setup", name = "TestApp", menuCategory: string | null = null, doNotPackElevateHelper = false) { if (process.env.DO_WINE !== "true") { return BluebirdPromise.resolve() } @@ -60,6 +60,12 @@ export async function doTest(outDir: string, perUser: boolean, productFilename = await assertThat(path.join(startMenuDir, `${productFilename}.lnk`)).isFile() } + if (doNotPackElevateHelper) { + await assertThat(path.join(instDir, name, "resources", "elevate.exe")).doesNotExist() + } else { + await assertThat(path.join(instDir, name, "resources", "elevate.exe")).isFile() + } + let fsAfter = await listFiles() let fsChanges = diff(fsBefore, fsAfter, driveC) diff --git a/test/src/windows/oneClickInstallerTest.ts b/test/src/windows/oneClickInstallerTest.ts index 2cdce3c02e5..fc3ac633f6c 100644 --- a/test/src/windows/oneClickInstallerTest.ts +++ b/test/src/windows/oneClickInstallerTest.ts @@ -18,19 +18,15 @@ test("one-click", app({ package: "TestApp", }, nsis: { - deleteAppDataOnUninstall: true + deleteAppDataOnUninstall: true, + doNotPackElevateHelper: true }, - }, - effectiveOptionComputed: async (it) => { - const defines = it[0] - expect(defines.DELETE_SUPPORTING_FILES_AFTER_INSTALL).not.toBeDefined() - return false } }, { signed: true, packed: async (context) => { - await doTest(context.outDir, true) - await expectUpdateMetadata(context, Arch.ia32, true, false) + await doTest(context.outDir, true, "TestApp Setup", "TestApp", null, true) + await expectUpdateMetadata(context, Arch.ia32, true) } })) @@ -211,18 +207,4 @@ test.ifAll.ifNotCiMac("web installer (default github)", app({ delete data.sha512 expect(data).toMatchSnapshot() }, -})) - -test("delete supporting files after install", app({ - targets: nsisTarget, - config: { - nsis: { - deleteSupportingFilesAfterInstall: true - } - }, - effectiveOptionComputed: async (it) => { - const defines = it[0] - expect(defines.DELETE_SUPPORTING_FILES_AFTER_INSTALL).toBeDefined() - return true - } })) \ No newline at end of file From af794b368e19f188b0f9763c6522aad09c4436eb Mon Sep 17 00:00:00 2001 From: Maria Date: Thu, 8 Jun 2017 16:43:39 +0300 Subject: [PATCH 4/4] Create Options.md --- docs/Options.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Options.md b/docs/Options.md index e30cb2c1716..a0f41dbfb7a 100644 --- a/docs/Options.md +++ b/docs/Options.md @@ -327,7 +327,6 @@ Some standard fields should be defined in the `package.json`. **Kind**: interface of [electron-builder](#module_electron-builder) **Properties** - * **`name`** String - The application name. * `description` String - The application description. * `homepage` String - The url to the project [homepage](https://docs.npmjs.com/files/package.json#homepage) (NuGet Package `projectUrl` (optional) or Linux Package URL (required)). @@ -340,6 +339,7 @@ Some standard fields should be defined in the `package.json`. * `repository` String | [RepositoryInfo](#RepositoryInfo) - The [repository](https://docs.npmjs.com/files/package.json#repository). * **`url`** String * `build` [Config](#Config) + ## Build Version Management -`CFBundleVersion` (macOS) and `FileVersion` (Windows) will be set automatically to `version.build_number` on CI server (Travis, AppVeyor, CircleCI and Bamboo supported). \ No newline at end of file +`CFBundleVersion` (macOS) and `FileVersion` (Windows) will be set automatically to `version.build_number` on CI server (Travis, AppVeyor, CircleCI and Bamboo supported).