diff --git a/docs/Options.md b/docs/Options.md index 846d18dce98..add1d8a3d4a 100644 --- a/docs/Options.md +++ b/docs/Options.md @@ -25,8 +25,6 @@ In the development `package.json` custom `build` field can be specified to custo As you can see, you need to customize MacOS options only if you want to provide custom `x, y`. Don't customize paths to background and icon, — just follow conventions. -Here documented only `electron-builder` specific options: - @@ -50,7 +48,7 @@ Here documented only `electron-builder` specific options: ## `.build` | Name | Description | --- | --- -| appId |

The application id. Used as [CFBundleIdentifier](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-102070) for MacOS and as [Application User Model ID](https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx) for Windows.

For windows only NSIS target supports it. Squirrel.Windows is not fixed yet.

Defaults to com.electron.${name}. It is strongly recommended that an explicit ID be set.

+| appId |

The application id. Used as [CFBundleIdentifier](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-102070) for MacOS and as [Application User Model ID](https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx) for Windows (NSIS target only, Squirrel.Windows not supported).

Defaults to com.electron.${name}. It is strongly recommended that an explicit ID be set.

| category |

*macOS-only.* The application category type, as shown in the Finder via *View -> Arrange by Application Category* when viewing the Applications directory.

For example, "category": "public.app-category.developer-tools" will set the application category to *Developer Tools*.

Valid values are listed in [Apple’s documentation](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html#//apple_ref/doc/uid/TP40009250-SW8).

| copyright | The human-readable copyright line for the app. Defaults to `Copyright © year author`. | asar |

Whether to package the application’s source code into an archive, using [Electron’s archive format](https://github.com/electron/asar). Defaults to true. Reasons why you may want to disable this feature are described in [an application packaging tutorial in Electron’s documentation](http://electron.atom.io/docs/latest/tutorial/application-packaging/#limitations-on-node-api/).

Or you can pass object of any asar options.

Node modules, that must be unpacked, will be detected automatically, you don’t need to explicitly set asar.unpackDir - please file issue if this doesn’t work.

@@ -136,7 +134,7 @@ See [NSIS target notes](https://github.com/electron-userland/electron-builder/wi | Name | Description | --- | --- | oneClick | One-click installation. Defaults to `true`. -| perMachine | Install per all users (per-machine). Defaults to `false`. +| perMachine |

Defaults to false.

If oneClick is true (default): Install per all users (per-machine).

If oneClick is false: no install mode installer page (choice per-machine or per-user), always install per-machine.

| allowElevation | *boring installer only.* Allow requesting for elevation. If false, user will have to restart installer with elevated permissions. Defaults to `true`. | runAfterFinish | *one-click installer only.* Run application after finish. Defaults to `true`. | guid | See [GUID vs Application Name](https://github.com/electron-userland/electron-builder/wiki/NSIS#guid-vs-application-name). diff --git a/src/metadata.ts b/src/metadata.ts index 11b521aeb25..dd8f9086317 100755 --- a/src/metadata.ts +++ b/src/metadata.ts @@ -85,9 +85,7 @@ export interface BuildMetadata { /* The application id. Used as [CFBundleIdentifier](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-102070) for MacOS and as - [Application User Model ID](https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx) for Windows. - - For windows only NSIS target supports it. Squirrel.Windows is not fixed yet. + [Application User Model ID](https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx) for Windows (NSIS target only, Squirrel.Windows not supported). Defaults to `com.electron.${name}`. It is strongly recommended that an explicit ID be set. */ @@ -388,7 +386,11 @@ export interface NsisOptions { readonly oneClick?: boolean | null /* - Install per all users (per-machine). Defaults to `false`. + Defaults to `false`. + + If `oneClick` is `true` (default): Install per all users (per-machine). + + If `oneClick` is `false`: no install mode installer page (choice per-machine or per-user), always install per-machine. */ readonly perMachine?: boolean | null diff --git a/src/packager/mac.ts b/src/packager/mac.ts index 525e132a20c..118756e4b1a 100644 --- a/src/packager/mac.ts +++ b/src/packager/mac.ts @@ -91,9 +91,13 @@ export async function createApp(opts: ElectronPackagerOptions, appOutDir: string const protocols = asArray(packager.devMetadata.build.protocols).concat(asArray(packager.platformSpecificBuildOptions.protocols)) if (protocols.length > 0) { appPlist.CFBundleURLTypes = protocols.map(protocol => { + const schemes = asArray(protocol.schemes) + if (schemes.length === 0) { + throw new Error(`Protocol "${protocol.name}": must be at least one scheme specified`) + } return { CFBundleURLName: protocol.name, - CFBundleURLSchemes: protocol.schemes.slice() + CFBundleURLSchemes: schemes.slice() } }) } diff --git a/templates/nsis/boringInstaller.nsh b/templates/nsis/boringInstaller.nsh index a7faf555275..7a239ae28f1 100644 --- a/templates/nsis/boringInstaller.nsh +++ b/templates/nsis/boringInstaller.nsh @@ -1,78 +1,89 @@ -!include multiUserUi.nsh +!include UAC.nsh + +!ifndef INSTALL_MODE_PER_ALL_USERS + !include multiUserUi.nsh +!endif !ifndef BUILD_UNINSTALLER Function StartApp !insertmacro UAC_AsUser_ExecShell "" "$SMPROGRAMS\${PRODUCT_FILENAME}.lnk" "" "" "" FunctionEnd - Function GuiInit - !insertmacro UAC_PageElevation_OnGuiInit - FunctionEnd - !define MUI_FINISHPAGE_RUN !define MUI_FINISHPAGE_RUN_FUNCTION "StartApp" - !define MUI_CUSTOMFUNCTION_GUIINIT GuiInit + !ifndef INSTALL_MODE_PER_ALL_USERS + !insertmacro PAGE_INSTALL_MODE + Function GuiInit + !insertmacro UAC_PageElevation_OnGuiInit + FunctionEnd - !insertmacro PAGE_INSTALL_MODE + !define MUI_CUSTOMFUNCTION_GUIINIT GuiInit + !endif !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_PAGE_FINISH !else - !insertmacro PAGE_INSTALL_MODE + !ifndef INSTALL_MODE_PER_ALL_USERS + !insertmacro PAGE_INSTALL_MODE + !endif !insertmacro MUI_UNPAGE_INSTFILES !endif !macro initMultiUser - !insertmacro UAC_PageElevation_OnInit + !ifdef INSTALL_MODE_PER_ALL_USERS + !insertmacro setInstallModePerAllUsers + !else + !insertmacro UAC_PageElevation_OnInit - ${If} ${UAC_IsInnerInstance} - ${AndIfNot} ${UAC_IsAdmin} - # special return value for outer instance so it knows we did not have admin rights - SetErrorLevel 0x666666 - Quit - ${EndIf} + ${If} ${UAC_IsInnerInstance} + ${AndIfNot} ${UAC_IsAdmin} + # special return value for outer instance so it knows we did not have admin rights + SetErrorLevel 0x666666 + Quit + ${EndIf} - !ifndef MULTIUSER_INIT_TEXT_ADMINREQUIRED - !define MULTIUSER_INIT_TEXT_ADMINREQUIRED "$(^Caption) requires administrator privileges." - !endif + !ifndef MULTIUSER_INIT_TEXT_ADMINREQUIRED + !define MULTIUSER_INIT_TEXT_ADMINREQUIRED "$(^Caption) requires administrator privileges." + !endif - !ifndef MULTIUSER_INIT_TEXT_POWERREQUIRED - !define MULTIUSER_INIT_TEXT_POWERREQUIRED "$(^Caption) requires at least Power User privileges." - !endif + !ifndef MULTIUSER_INIT_TEXT_POWERREQUIRED + !define MULTIUSER_INIT_TEXT_POWERREQUIRED "$(^Caption) requires at least Power User privileges." + !endif - !ifndef MULTIUSER_INIT_TEXT_ALLUSERSNOTPOSSIBLE - !define MULTIUSER_INIT_TEXT_ALLUSERSNOTPOSSIBLE "Your user account does not have sufficient privileges to install $(^Name) for all users of this computer." - !endif + !ifndef MULTIUSER_INIT_TEXT_ALLUSERSNOTPOSSIBLE + !define MULTIUSER_INIT_TEXT_ALLUSERSNOTPOSSIBLE "Your user account does not have sufficient privileges to install $(^Name) for all users of this computer." + !endif - # checks registry for previous installation path (both for upgrading, reinstall, or uninstall) - StrCpy $hasPerMachineInstallation "0" - StrCpy $hasPerUserInstallation "0" + # checks registry for previous installation path (both for upgrading, reinstall, or uninstall) + StrCpy $hasPerMachineInstallation "0" + StrCpy $hasPerUserInstallation "0" - # set installation mode to setting from a previous installation - ReadRegStr $perMachineInstallationFolder HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation - ${if} $perMachineInstallationFolder != "" - StrCpy $hasPerMachineInstallation "1" - ${endif} + # set installation mode to setting from a previous installation + ReadRegStr $perMachineInstallationFolder HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation + ${if} $perMachineInstallationFolder != "" + StrCpy $hasPerMachineInstallation "1" + ${endif} - ReadRegStr $perUserInstallationFolder HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation - ${if} $perUserInstallationFolder != "" - StrCpy $hasPerUserInstallation "1" - ${endif} + ReadRegStr $perUserInstallationFolder HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation + ${if} $perUserInstallationFolder != "" + StrCpy $hasPerUserInstallation "1" + ${endif} - ${if} $hasPerUserInstallation == "1" - ${andif} $hasPerMachineInstallation == "0" - !insertmacro setInstallModePerUser - ${elseif} $hasPerUserInstallation == "0" - ${andif} $hasPerMachineInstallation == "1" - !insertmacro setInstallModePerAllUsers - ${else} - # if there is no installation, or there is both per-user and per-machine - !ifdef INSTALL_MODE_PER_ALL_USERS - !insertmacro setInstallModePerAllUsers - !else + ${if} $hasPerUserInstallation == "1" + ${andif} $hasPerMachineInstallation == "0" !insertmacro setInstallModePerUser - !endif - ${endif} + ${elseif} $hasPerUserInstallation == "0" + ${andif} $hasPerMachineInstallation == "1" + !insertmacro setInstallModePerAllUsers + ${else} + # if there is no installation, or there is both per-user and per-machine + !ifdef INSTALL_MODE_PER_ALL_USERS + !insertmacro setInstallModePerAllUsers + !else + !insertmacro setInstallModePerUser + !endif + ${endif} + !endif !macroend !include "langs.nsh" \ No newline at end of file diff --git a/templates/nsis/install.nsh b/templates/nsis/install.nsh index 572254bca58..57f8aa68a7e 100644 --- a/templates/nsis/install.nsh +++ b/templates/nsis/install.nsh @@ -16,7 +16,13 @@ ${IfNot} ${Silent} !endif ${endif} -!insertmacro CHECK_APP_RUNNING "install" +!ifdef ONE_CLICK + !insertmacro CHECK_APP_RUNNING "install" +!else + ${IfNot} ${UAC_IsInnerInstance} + !insertmacro CHECK_APP_RUNNING "install" + ${endif} +!endif ReadRegStr $R0 SHCTX "${UNINSTALL_REGISTRY_KEY}" UninstallString ${if} $R0 != "" diff --git a/templates/nsis/installer.nsi b/templates/nsis/installer.nsi index ad71b86fd5e..ad759d26770 100644 --- a/templates/nsis/installer.nsi +++ b/templates/nsis/installer.nsi @@ -3,6 +3,12 @@ !include "multiUser.nsh" !include "allowOnlyOneInstallerInstace.nsh" +!ifdef INSTALL_MODE_PER_ALL_USERS + RequestExecutionLevel admin +!else + RequestExecutionLevel user +!endif + !ifdef ONE_CLICK !include "oneClick.nsh" !else diff --git a/templates/nsis/multiUserUi.nsh b/templates/nsis/multiUserUi.nsh index aed0ccdf502..99e1f2e3c6f 100755 --- a/templates/nsis/multiUserUi.nsh +++ b/templates/nsis/multiUserUi.nsh @@ -1,7 +1,4 @@ !include nsDialogs.nsh -!include UAC.nsh - -RequestExecutionLevel user Var HasTwoAvailableOptions Var RadioButtonLabel1 diff --git a/templates/nsis/oneClick.nsh b/templates/nsis/oneClick.nsh index 7c4178029ce..1b7459133d7 100644 --- a/templates/nsis/oneClick.nsh +++ b/templates/nsis/oneClick.nsh @@ -18,12 +18,6 @@ !insertmacro MUI_LANGUAGE "English" -!ifdef INSTALL_MODE_PER_ALL_USERS - RequestExecutionLevel admin -!else - RequestExecutionLevel user -!endif - !macro initMultiUser !ifdef INSTALL_MODE_PER_ALL_USERS !insertmacro setInstallModePerAllUsers diff --git a/test/src/nsisTest.ts b/test/src/nsisTest.ts index 99cb4a7ff2f..b1bd274cc5f 100644 --- a/test/src/nsisTest.ts +++ b/test/src/nsisTest.ts @@ -117,6 +117,18 @@ test.ifNotCiOsx("boring", app({ } }, {signed: true})) +test.ifNotCiOsx("boring, only perMachine", app({ + targets: nsisTarget, + devMetadata: { + build: { + nsis: { + oneClick: false, + perMachine: true, + } + } + } +})) + test.ifNotCiOsx("installerHeaderIcon", () => { let headerIconPath: string | null = null return assertPack("test-app-one", {