diff --git a/docs/Options.md b/docs/Options.md
index 3a2da9eedb6..4166ccccea6 100644
--- a/docs/Options.md
+++ b/docs/Options.md
@@ -168,6 +168,7 @@ NSIS only, [in progress](https://github.com/electron-userland/electron-builder/i
| **ext** | The extension (minus the leading period). e.g. `png`
| **name** | The name. e.g. `PNG`
| description | *windows-only.* The description.
+| icon | *windows-only.* The path to icon (`.ico`), relative to `build` (build resources directory). Defaults to `${ext}.ico`.
## `.directories`
diff --git a/src/metadata.ts b/src/metadata.ts
index c5b933b535b..58f54449e4b 100755
--- a/src/metadata.ts
+++ b/src/metadata.ts
@@ -493,6 +493,11 @@ export interface FileAssociation {
*windows-only.* The description.
*/
readonly description?: string
+
+ /*
+ *windows-only.* The path to icon (`.ico`), relative to `build` (build resources directory). Defaults to `${ext}.ico`.
+ */
+ readonly icon?: string
}
/*
diff --git a/src/targets/nsis.ts b/src/targets/nsis.ts
index c6abfd75ab0..a64b500442d 100644
--- a/src/targets/nsis.ts
+++ b/src/targets/nsis.ts
@@ -1,5 +1,5 @@
import { WinPackager } from "../winPackager"
-import { Arch, NsisOptions } from "../metadata"
+import { Arch, NsisOptions, FileAssociation } from "../metadata"
import { exec, debug, doSpawn, handleProcess, use } from "../util/util"
import * as path from "path"
import { Promise as BluebirdPromise } from "bluebird"
@@ -30,10 +30,17 @@ export default class NsisTarget extends Target {
private readonly nsisTemplatesDir = path.join(__dirname, "..", "..", "templates", "nsis")
+ private readonly fileAssociations: Array
+
constructor(private packager: WinPackager, private outDir: string) {
super("nsis")
this.options = packager.info.devMetadata.build.nsis || Object.create(null)
+
+ // CFBundleTypeName
+ // https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-101685
+ // CFBundleTypeExtensions
+ this.fileAssociations = asArray(packager.devMetadata.build.fileAssociations).concat(asArray(packager.platformSpecificBuildOptions.fileAssociations))
}
async build(arch: Arch, appOutDir: string) {
@@ -221,24 +228,26 @@ export default class NsisTarget extends Target {
const binDir = process.platform === "darwin" ? "mac" : (process.platform === "win32" ? "Bin" : "linux")
const nsisPath = await nsisPathPromise
- const packager = this.packager
- // CFBundleTypeName
- // https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-101685
- // CFBundleTypeExtensions
- const fileAssociations = asArray(packager.devMetadata.build.fileAssociations).concat(asArray(packager.platformSpecificBuildOptions.fileAssociations))
-
let script = originalScript
const customInclude = await this.getResource(this.options.include, "installer.nsh")
if (customInclude != null) {
script = `!include "${customInclude}"\n!addincludedir "${this.packager.buildResourcesDir}"\n${script}`
}
- if (fileAssociations.length !== 0) {
+ if (this.fileAssociations.length !== 0) {
script = "!include FileAssociation.nsh\n" + script
if (isInstaller) {
let registerFileAssociationsScript = ""
- for (let item of fileAssociations) {
- const icon = '"$INSTDIR\\${APP_EXECUTABLE_FILENAME},0"'
+ for (let item of this.fileAssociations) {
+ const customIcon = await this.getResource(item.icon, `${normalizeExt(item.ext)}.ico`)
+ let installedIconPath = "${APP_EXECUTABLE_FILENAME},0"
+ if (customIcon != null) {
+ installedIconPath = `resources\\${path.basename(customIcon)}`
+ //noinspection SpellCheckingInspection
+ registerFileAssociationsScript += ` File "/oname=${installedIconPath}" "${customIcon}"\n`
+ }
+
+ const icon = `"$INSTDIR\\${installedIconPath}"`
const commandText = `"Open with ${this.packager.appInfo.productName}"`
const command = '"$INSTDIR\\${APP_EXECUTABLE_FILENAME} $\\"%1$\\""'
registerFileAssociationsScript += ` !insertmacro APP_ASSOCIATE "${normalizeExt(item.ext)}" "${item.name}" "${item.description || ""}" ${icon} ${commandText} ${command}\n`
@@ -247,7 +256,7 @@ export default class NsisTarget extends Target {
}
else {
let unregisterFileAssociationsScript = ""
- for (let item of fileAssociations) {
+ for (let item of this.fileAssociations) {
unregisterFileAssociationsScript += ` !insertmacro APP_UNASSOCIATE "${normalizeExt(item.ext)}" "${item.name}"\n`
}
script = `!macro unregisterFileAssociations\n${unregisterFileAssociationsScript}!macroend\n${script}`
diff --git a/test/src/nsisTest.ts b/test/src/nsisTest.ts
index b80d1664822..72695c35640 100644
--- a/test/src/nsisTest.ts
+++ b/test/src/nsisTest.ts
@@ -28,6 +28,11 @@ test.ifDevOrLinuxCi("perMachine, no run after finish", app({
},
}
}
+}, {
+ projectDirCreated: projectDir => {
+ let headerIconPath = path.join(projectDir, "build", "foo.ico")
+ return copy(getTestAsset("headerIcon.ico"), headerIconPath)
+ },
}))
test.ifNotCiOsx("boring", app({