diff --git a/README.md b/README.md index a2ed4da0bcf..840ff84c38c 100755 --- a/README.md +++ b/README.md @@ -162,7 +162,8 @@ and other distributable formats. ## Community -[electron-builder](https://electron-builder.slack.com/shared_invite/MTMzMTc5NTcyNTAzLTE0ODUzNzE4MTctYzBhNGY1NjljYg) on Slack. Please use [threads](https://get.slack.help/hc/en-us/articles/115000769927-Message-threads). +[electron-builder](https://electron-builder.slack.com/shared_invite/MTMzMTc5NTcyNTAzLTE0ODUzNzE4MTctYzBhNGY1NjljYg) on Slack (please use [threads](https://get.slack.help/hc/en-us/articles/115000769927-Message-threads)). +Public [archive](http://electron-builder.slackarchive.io) without registration. ## Further Reading See the [Wiki](https://github.com/electron-userland/electron-builder/wiki) for more documentation. diff --git a/packages/electron-builder/src/targets/nsis.ts b/packages/electron-builder/src/targets/nsis.ts index 6d21e322a8d..5e5549e12db 100644 --- a/packages/electron-builder/src/targets/nsis.ts +++ b/packages/electron-builder/src/targets/nsis.ts @@ -70,6 +70,7 @@ export default class NsisTarget extends Target { const installerFilename = `${appInfo.productFilename} Setup ${version}.exe` const options = this.options const iconPath = await packager.getResource(options.installerIcon, "installerIcon.ico") || await packager.getIconPath() + const oneClick = options.oneClick !== false const installerPath = path.join(this.outDir, installerFilename) const guid = options.guid || await BluebirdPromise.promisify(uuid5)({namespace: ELECTRON_BUILDER_NS_UUID, name: appInfo.id}) @@ -78,7 +79,7 @@ export default class NsisTarget extends Target { APP_GUID: guid, PRODUCT_NAME: appInfo.productName, PRODUCT_FILENAME: appInfo.productFilename, - APP_FILENAME: appInfo.name, + APP_FILENAME: (!oneClick || options.perMachine === true) && /^[-_0-9a-zA-Z ]+$/.test(appInfo.productFilename) ? appInfo.productFilename : appInfo.name, APP_DESCRIPTION: appInfo.description, VERSION: version, @@ -97,8 +98,6 @@ export default class NsisTarget extends Target { defines[arch === Arch.x64 ? "APP_64" : "APP_32"] = await file } - const oneClick = options.oneClick !== false - const installerHeader = oneClick ? null : await packager.getResource(options.installerHeader, "installerHeader.bmp") if (installerHeader != null) { defines.MUI_HEADERIMAGE = null diff --git a/packages/electron-builder/templates/nsis/boringInstaller.nsh b/packages/electron-builder/templates/nsis/boringInstaller.nsh index bc31e4862f3..6e5c007e20b 100644 --- a/packages/electron-builder/templates/nsis/boringInstaller.nsh +++ b/packages/electron-builder/templates/nsis/boringInstaller.nsh @@ -21,11 +21,11 @@ !ifdef LICENSE_FILE Function licensePre - ${GetParameters} $R0 - ${GetOptions} $R0 "--update" $R1 - ${IfNot} ${Errors} - Abort - ${endif} + ${GetParameters} $R0 + ${GetOptions} $R0 "--update" $R1 + ${IfNot} ${Errors} + Abort + ${endif} FunctionEnd !define MUI_PAGE_CUSTOMFUNCTION_PRE licensePre @@ -34,11 +34,6 @@ !ifndef INSTALL_MODE_PER_ALL_USERS !insertmacro PAGE_INSTALL_MODE - Function GuiInit - !insertmacro UAC_PageElevation_OnGuiInit - FunctionEnd - - !define MUI_CUSTOMFUNCTION_GUIINIT GuiInit !endif !ifdef allowToChangeInstallationDirectory @@ -59,17 +54,11 @@ !ifdef INSTALL_MODE_PER_ALL_USERS !insertmacro setInstallModePerAllUsers !else - !insertmacro UAC_PageElevation_OnInit - ${If} ${UAC_IsInnerInstance} - ${If} ${UAC_IsAdmin} - !insertmacro setInstallModePerAllUsers - Goto functionEnd - ${else} - # special return value for outer instance so it knows we did not have admin rights - SetErrorLevel 0x666666 - Quit - ${EndIf} + ${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 @@ -102,18 +91,18 @@ ${GetParameters} $R0 ${GetOptions} $R0 "/allusers" $R1 ${IfNot} ${Errors} - !insertmacro setInstallModePerAllUsers - Goto functionEnd + StrCpy $hasPerMachineInstallation "1" + StrCpy $hasPerUserInstallation "0" ${EndIf} ${GetOptions} $R0 "/currentuser" $R1 ${IfNot} ${Errors} - !insertmacro setInstallModePerUser - Goto functionEnd + StrCpy $hasPerMachineInstallation "0" + StrCpy $hasPerUserInstallation "1" ${EndIf} ${if} $hasPerUserInstallation == "1" - ${andif} $hasPerMachineInstallation == "0" + ${andif} $hasPerMachineInstallation == "0" !insertmacro setInstallModePerUser ${elseif} $hasPerUserInstallation == "0" ${andif} $hasPerMachineInstallation == "1" @@ -126,8 +115,6 @@ !insertmacro setInstallModePerUser !endif ${endif} - - functionEnd: !endif !macroend diff --git a/packages/electron-builder/templates/nsis/multiUser.nsh b/packages/electron-builder/templates/nsis/multiUser.nsh index 6a00c8fc901..038ae27ff96 100644 --- a/packages/electron-builder/templates/nsis/multiUser.nsh +++ b/packages/electron-builder/templates/nsis/multiUser.nsh @@ -1,4 +1,5 @@ !include FileFunc.nsh +!include UAC.nsh !define FOLDERID_UserProgramFiles {5CD7AEE2-2219-4A67-B85D-6C9CE15660CB} !define KF_FLAG_CREATE 0x00008000 @@ -20,7 +21,12 @@ Var installMode !macro setInstallModePerUser StrCpy $installMode CurrentUser SetShellVarContext current - !ifndef BUILD_UNINSTALLER + + # сhecks registry for previous installation path + ReadRegStr $perUserInstallationFolder HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation + ${if} $perUserInstallationFolder != "" + StrCpy $INSTDIR $perUserInstallationFolder + ${else} StrCpy $0 "$LocalAppData\Programs" # Win7 has a per-user programfiles known folder and this can be a non-default location System::Call 'Shell32::SHGetKnownFolderPath(g "${FOLDERID_UserProgramFiles}",i ${KF_FLAG_CREATE},i0,*i.r2)i.r1' @@ -30,15 +36,7 @@ Var installMode System::Call 'Ole32::CoTaskMemFree(ir2)' ${endif} StrCpy $INSTDIR "$0\${APP_FILENAME}" - !endif - - # сhecks registry for previous installation path — for uninstall only, currently, installation path is not customizable - ReadRegStr $perUserInstallationFolder HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation - !ifdef BUILD_UNINSTALLER - ${if} $perUserInstallationFolder != "" - StrCpy $INSTDIR $perUserInstallationFolder - ${endif} - !endif + ${endif} !macroend !endif @@ -49,33 +47,31 @@ Var installMode StrCpy $installMode all SetShellVarContext all - StrCpy $0 "$PROGRAMFILES" - !ifdef APP_64 - ${if} ${RunningX64} - StrCpy $0 "$PROGRAMFILES64" + !ifdef BUILD_UNINSTALLER + ${IfNot} ${UAC_IsAdmin} + ShowWindow $HWNDPARENT ${SW_HIDE} + !insertmacro UAC_RunElevated + Quit ${endif} !endif - !ifdef MENU_FILENAME - StrCpy $0 "$0\${MENU_FILENAME}" - !endif - - StrCpy $INSTDIR "$0\${APP_FILENAME}" + # сheck registry for previous installation path + ReadRegStr $perMachineInstallationFolder HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation + ${if} $perMachineInstallationFolder != "" + StrCpy $INSTDIR $perMachineInstallationFolder + ${else} + StrCpy $0 "$PROGRAMFILES" + !ifdef APP_64 + ${if} ${RunningX64} + StrCpy $0 "$PROGRAMFILES64" + ${endif} + !endif - ${if} $installMode == "all" - StrCpy $0 "/allusers" - StrCpy $1 "" - ${else} - StrCpy $0 "/currentuser" - StrCpy $1 " (only current user)" - ${endif} + !ifdef MENU_FILENAME + StrCpy $0 "$0\${MENU_FILENAME}" + !endif - # сhecks registry for previous installation path — for uninstall only, currently, installation path is not customizable - ReadRegStr $perMachineInstallationFolder HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation - !ifdef BUILD_UNINSTALLER - ${if} $perMachineInstallationFolder != "" - StrCpy $INSTDIR $perMachineInstallationFolder - ${endif} - !endif + StrCpy $INSTDIR "$0\${APP_FILENAME}" + ${endif} !macroend !endif diff --git a/packages/electron-builder/templates/nsis/multiUserUi.nsh b/packages/electron-builder/templates/nsis/multiUserUi.nsh index 4d5e4025d68..2270d478c64 100755 --- a/packages/electron-builder/templates/nsis/multiUserUi.nsh +++ b/packages/electron-builder/templates/nsis/multiUserUi.nsh @@ -37,12 +37,22 @@ Var RadioButtonLabel1 ${GetParameters} $R0 ${GetOptions} $R0 "/allusers" $R1 ${IfNot} ${Errors} + StrCpy $hasPerMachineInstallation "1" + StrCpy $hasPerUserInstallation "0" + ${IfNot} ${UAC_IsAdmin} + ShowWindow $HWNDPARENT ${SW_HIDE} + !insertmacro UAC_RunElevated + Quit + ${endif} + !insertmacro setInstallModePerAllUsers Abort ${EndIf} ${GetOptions} $R0 "/currentuser" $R1 ${IfNot} ${Errors} + StrCpy $hasPerMachineInstallation "0" + StrCpy $hasPerUserInstallation "1" !insertmacro setInstallModePerUser Abort ${EndIf} @@ -52,11 +62,17 @@ Var RadioButtonLabel1 # so (for uninstallation) just checking UAC_IsAdmin would probably be enought to determine if it's a per-user or per-machine. However, user can run the uninstall.exe from the folder itself !ifdef BUILD_UNINSTALLER ${if} $hasPerUserInstallation == "1" - ${andif} $hasPerMachineInstallation == "0" + ${andif} $hasPerMachineInstallation == "0" !insertmacro setInstallModePerUser Abort ${elseif} $hasPerUserInstallation == "0" - ${andif} $hasPerMachineInstallation == "1" + ${andif} $hasPerMachineInstallation == "1" + ${IfNot} ${UAC_IsAdmin} + ShowWindow $HWNDPARENT ${SW_HIDE} + !insertmacro UAC_RunElevated + Quit + ${endif} + !insertmacro setInstallModePerAllUsers Abort ${endif} @@ -66,6 +82,7 @@ Var RadioButtonLabel1 !insertmacro MUI_HEADER_TEXT "Choose Installation Options" "Who should this application be installed for?" !endif + !insertmacro MUI_PAGE_FUNCTION_CUSTOM PRE nsDialogs::Create 1018 Pop $MultiUser.InstallModePage @@ -126,32 +143,38 @@ Var RadioButtonLabel1 SendMessage $MultiUser.InstallModePage.AllUsers ${BM_GETCHECK} 0 0 $MultiUser.InstallModePage.ReturnValue ${if} $MultiUser.InstallModePage.ReturnValue = ${BST_CHECKED} - !insertmacro setInstallModePerAllUsers ${IfNot} ${UAC_IsAdmin} - !ifdef MULTIUSER_INSTALLMODE_ALLOW_ELEVATION - GetDlgItem $9 $HWNDParent 1 - System::Call user32::GetFocus()i.s - EnableWindow $9 0 ;disable next button - !insertmacro UAC_PageElevation_RunElevated - EnableWindow $9 1 - System::Call user32::SetFocus(is) ;Do we need WM_NEXTDLGCTL or can we get away with this hack? - ${If} $2 = 0x666666 ;our special return, the new process was not admin after all - MessageBox mb_iconExclamation "You need to login with an account that is a member of the admin group to continue..." - Abort - ${ElseIf} $0 = 1223 ;cancel - Abort - ${Else} - ${If} $0 <> 0 - ${If} $0 = 1062 - MessageBox mb_iconstop "Unable to elevate, Secondary Logon service not running!" - ${Else} - MessageBox mb_iconstop "Unable to elevate, error $0" - ${EndIf} - Abort + ShowWindow $HWNDPARENT ${SW_HIDE} + !insertmacro UAC_RunElevated + ${Switch} $0 + ${Case} 0 + ${If} $1 = 1 + Quit ;we are the outer process, the inner process has done its work (ExitCode is $2), we are done ${EndIf} - ${EndIf} - Quit - !endif + ${If} $1 = 3 ;RunAs completed successfully, but with a non-admin user + ${OrIf} $2 = 0x666666 ;our special return, the new process was not admin after all + MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "You need to login with an account that is a member of the admin group to continue..." + ${EndIf} + ${Break} + ${Case} 1223 ;user aborted + ;MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "This option requires admin privileges, aborting!" + ;Quit ; instead of quit just abort going to the next page, and stay in the radiobuttons + ${Break} + ${Case} 1062 + MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "Logon service not running, aborting!" ; "Unable to elevate, Secondary Logon service not running!" + ;Quit ; instead of quit just abort going to the next page, and stay in the radiobuttons + ${Break} + ${Default} + MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "Unable to elevate, error $0" + ;Quit ; instead of quit just abort going to the next page, and stay in the radiobuttons + ${Break} + ${EndSwitch} + + ShowWindow $HWNDPARENT ${SW_SHOW} + BringToFront + Abort + ${else} + !insertmacro setInstallModePerAllUsers ${endif} ${else} !insertmacro setInstallModePerUser diff --git a/yarn.lock b/yarn.lock index 5c8cbfda4b7..bd9aa852e1e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2594,7 +2594,7 @@ speedometer@~0.1.2: version "0.1.4" resolved "https://registry.yarnpkg.com/speedometer/-/speedometer-0.1.4.tgz#9876dbd2a169d3115402d48e6ea6329c8816a50d" -sprintf-js@^1.0.3, sprintf-js@~1.0.2: +sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -2768,8 +2768,8 @@ ts-babel@^1.3.5: source-map-support "^0.4.10" tslint@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-4.3.1.tgz#28f679c53ca4b273688bcb6fcf0dde7ff1bb2169" + version "4.4.2" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-4.4.2.tgz#b14cb79ae039c72471ab4c2627226b940dda19c6" dependencies: babel-code-frame "^6.20.0" colors "^1.1.2" @@ -2778,7 +2778,6 @@ tslint@^4.3.1: glob "^7.1.1" optimist "~0.6.0" resolve "^1.1.7" - underscore.string "^3.3.4" update-notifier "^1.0.2" tunnel-agent@^0.4.3, tunnel-agent@~0.4.1: @@ -2816,13 +2815,6 @@ uglify-to-browserify@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" -underscore.string@^3.3.4: - version "3.3.4" - resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-3.3.4.tgz#2c2a3f9f83e64762fdc45e6ceac65142864213db" - dependencies: - sprintf-js "^1.0.3" - util-deprecate "^1.0.2" - unzip-response@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-1.0.2.tgz#b984f0877fc0a89c2c773cc1ef7b5b232b5b06fe" @@ -2850,7 +2842,7 @@ utf8-byte-length@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz#f45f150c4c66eee968186505ab93fcbb8ad6bf61" -util-deprecate@^1.0.2, util-deprecate@~1.0.1: +util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"