diff --git a/docker/nsis.sh b/docker/nsis.sh index 3d76d09d05..a192f48203 100755 --- a/docker/nsis.sh +++ b/docker/nsis.sh @@ -5,7 +5,7 @@ rm -rf Docs rm -rf NSIS.chm rm -rf Examples rm -rf Plugins/x86-ansi -unlink makensisw.exe +rm -f makensisw.exe # nsProcess plugin curl -L http://nsis.sourceforge.net/mediawiki/images/1/18/NsProcess.zip > a.zip diff --git a/docs/Options.md b/docs/Options.md index 99d20ee95c..d6e96845c0 100644 --- a/docs/Options.md +++ b/docs/Options.md @@ -130,6 +130,7 @@ See [NSIS target notes](https://github.com/electron-userland/electron-builder/wi | allowElevation | Allow requesting for elevation. If false, user will have to restart installer with elevated permissions. Defaults to `true`. | oneClick | One-click installation. Defaults to `true`. | installerHeader | *boring installer only.* `MUI_HEADERIMAGE`, relative to the project directory. Defaults to `build/installerHeader.bmp` +| headerIcon | *one-click installer only.* The path to header icon (above the progress bar), relative to the project directory. Defaults to `build/headerIcon.ico` or application icon. ### `.build.linux` diff --git a/src/metadata.ts b/src/metadata.ts index 9ef32a93de..be0eb9ab83 100755 --- a/src/metadata.ts +++ b/src/metadata.ts @@ -373,6 +373,11 @@ export interface NsisOptions { *boring installer only.* `MUI_HEADERIMAGE`, relative to the project directory. Defaults to `build/installerHeader.bmp` */ readonly installerHeader?: string | null + + /* + *one-click installer only.* The path to header icon (above the progress bar), relative to the project directory. Defaults to `build/headerIcon.ico` or application icon. + */ + readonly headerIcon?: string | null } /* diff --git a/src/targets/nsis.ts b/src/targets/nsis.ts index 5e71085f31..7001104fd6 100644 --- a/src/targets/nsis.ts +++ b/src/targets/nsis.ts @@ -15,9 +15,9 @@ import semver = require("semver") //noinspection JSUnusedLocalSymbols const __awaiter = require("../util/awaiter") -const NSIS_VERSION = "nsis-3.0.0-rc.1.2" +const NSIS_VERSION = "nsis-3.0.0-rc.1.3" //noinspection SpellCheckingInspection -const NSIS_SHA2 = "d96f714ba552a5ebccf2593ed3fee1b072b67e7bfd1b90d66a5eb0cd3ca41d16" +const NSIS_SHA2 = "77bca57e784372dea1b69b0571d89d5a1c879c51d80d7c503f283a2e7de5f072" //noinspection SpellCheckingInspection const ELECTRON_BUILDER_NS_UUID = "50e065bc-3134-11e6-9bab-38c9862bdaf3" @@ -75,23 +75,20 @@ export default class NsisTarget extends Target { defines[arch === Arch.x64 ? "APP_64" : "APP_32"] = await file } - let installerHeader = this.options.installerHeader - if (installerHeader === undefined) { - const resourceList = await packager.resourceList - if (resourceList.includes("installerHeader.bmp")) { - installerHeader = path.join(packager.buildResourcesDir, "installerHeader.bmp") - } - } - else { - installerHeader = path.resolve(packager.projectDir, installerHeader) - } + const oneClick = this.options.oneClick !== false + const installerHeader = oneClick ? null : await this.getResource(this.options.installerHeader, "installerHeader.bmp") if (installerHeader != null) { defines.MUI_HEADERIMAGE = null defines.MUI_HEADERIMAGE_RIGHT = null defines.MUI_HEADERIMAGE_BITMAP = installerHeader } + const headerIcon = oneClick ? await this.getResource(this.options.installerHeader, "headerIcon.ico") : null + if (headerIcon != null) { + defines.HEADER_ICO = headerIcon + } + if (this.options.perMachine === true) { defines.MULTIUSER_INSTALLMODE_DEFAULT_ALLUSERS = null } @@ -132,7 +129,6 @@ export default class NsisTarget extends Target { defines.COMPRESS = "auto" } - const oneClick = this.options.oneClick !== false if (oneClick) { defines.ONE_CLICK = null } @@ -150,6 +146,21 @@ export default class NsisTarget extends Target { this.packager.dispatchArtifactCreated(installerPath, `${appInfo.name}-Setup-${version}.exe`) } + protected async getResource(custom: string | n, name: string): Promise { + let result = custom + if (result === undefined) { + const resourceList = await this.packager.resourceList + if (resourceList.includes(name)) { + return path.join(this.packager.buildResourcesDir, name) + } + } + else { + return path.resolve(this.packager.projectDir, result) + } + + return null + } + private static async executeMakensis(defines: any, commands: any) { const args: Array = [] for (let name of Object.keys(defines)) { diff --git a/templates/nsis/installer.nsi b/templates/nsis/installer.nsi index 3f405a384f..7e5f30a28a 100644 --- a/templates/nsis/installer.nsi +++ b/templates/nsis/installer.nsi @@ -57,7 +57,11 @@ Section "install" SetDetailsPrint none !ifdef ONE_CLICK - SpiderBanner::Show /MODERN + !ifdef HEADER_ICO + SpiderBanner::Show /MODERN /ICON "${HEADER_ICO}" + !else + SpiderBanner::Show /MODERN + !endif !endif !insertmacro CHECK_APP_RUNNING "install" diff --git a/test/fixtures/test-app-one/headerIcon.ico b/test/fixtures/test-app-one/headerIcon.ico new file mode 100644 index 0000000000..0d0e4db069 --- /dev/null +++ b/test/fixtures/test-app-one/headerIcon.ico @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e6de156262ce7d0cd332add2a1a80ecc7b22aefaa4d491d35d345faca6b695b +size 370070 diff --git a/test/src/winPackagerTest.ts b/test/src/winPackagerTest.ts index 3132b8ae6c..de8115da81 100755 --- a/test/src/winPackagerTest.ts +++ b/test/src/winPackagerTest.ts @@ -62,6 +62,24 @@ test.ifNotCiOsx("nsis boring", () => assertPack("test-app-one", _signed({ } )) +test.ifNotCiOsx("nsis, headerIcon", () => { + let headerIconPath: string | null = null + return assertPack("test-app-one", { + targets: Platform.WINDOWS.createTarget(["nsis"]), + effectiveOptionComputed: options => { + const defines = options[0] + assertThat(defines.HEADER_ICO).isEqualTo(headerIconPath) + return false + } + }, { + tempDirCreated: projectDir => { + headerIconPath = path.join(projectDir, "build", "headerIcon.ico") + return rename(path.join(projectDir, "headerIcon.ico"), headerIconPath) + } + } + ) +}) + test.ifNotCiOsx("nsis boring, MUI_HEADER", () => { let installerHeaderPath: string | null = null return assertPack("test-app-one", {