From 7c2973dda46434827fc43a1c330bbf9da3923053 Mon Sep 17 00:00:00 2001 From: develar Date: Wed, 25 Jan 2017 22:08:22 +0100 Subject: [PATCH] feat(electron-updater): cannot use updater without administrator privileges Close #1133 --- README.md | 4 + packages/electron-builder/src/targets/nsis.ts | 7 +- packages/electron-updater/src/AppUpdater.ts | 13 +++- packages/electron-updater/src/NsisUpdater.ts | 78 ++++++++++++++----- yarn.lock | 4 +- 5 files changed, 80 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 451e5bee610..a2ed4da0bcf 100755 --- a/README.md +++ b/README.md @@ -160,6 +160,10 @@ and other distributable formats. [Donate with PayPal.](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=W6V79R2RGCCHL) +## 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). + ## 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 d5e8729f6a7..5b425daad41 100644 --- a/packages/electron-builder/src/targets/nsis.ts +++ b/packages/electron-builder/src/targets/nsis.ts @@ -11,10 +11,11 @@ import { unlink, readFile } from "fs-extra-p" import { NsisOptions } from "../options/winOptions" import { Target, Arch } from "electron-builder-core" import sanitizeFileName from "sanitize-filename" +import { copyFile } from "electron-builder-util/out/fs" -const NSIS_VERSION = "3.0.4" +const NSIS_VERSION = "3.0.1.5" //noinspection SpellCheckingInspection -const NSIS_SHA2 = "c29883cb9a04733489590420b910ea7a91ba0f9b776fe4c647d9801f23175225" +const NSIS_SHA2 = "cf996b4209f302c1f6b379a6b2090ad0d51a360daf24d1828eeceafd1617a976" //noinspection SpellCheckingInspection const ELECTRON_BUILDER_NS_UUID = "50e065bc-3134-11e6-9bab-38c9862bdaf3" @@ -45,6 +46,8 @@ export default class NsisTarget extends Target { private async doBuild(appOutDir: string, arch: Arch) { log(`Packaging NSIS installer for arch ${Arch[arch]}`) + await copyFile(path.join(await nsisPathPromise, "elevate.exe"), path.join(appOutDir, "resources", "elevate.exe")) + const packager = this.packager const archiveFile = path.join(this.outDir, `${packager.appInfo.name}-${packager.appInfo.version}-${Arch[arch]}.nsis.7z`) return await archive(packager.config.compression, "7z", archiveFile, appOutDir, true) diff --git a/packages/electron-updater/src/AppUpdater.ts b/packages/electron-updater/src/AppUpdater.ts index b8ff1fc935c..3a38b53c6dc 100644 --- a/packages/electron-updater/src/AppUpdater.ts +++ b/packages/electron-updater/src/AppUpdater.ts @@ -204,7 +204,18 @@ export abstract class AppUpdater extends EventEmitter { if (this.logger != null) { this.logger.info(`Downloading update from ${fileInfo.url}`) } - return await this.doDownloadUpdate(versionInfo, fileInfo) + + try { + return await this.doDownloadUpdate(versionInfo, fileInfo) + } + catch (e) { + this.dispatchError(e) + throw e + } + } + + protected dispatchError(e: Error) { + this.emit("error", e, (e.stack || e).toString()) } protected async abstract doDownloadUpdate(versionInfo: VersionInfo, fileInfo: FileInfo): Promise diff --git a/packages/electron-updater/src/NsisUpdater.ts b/packages/electron-updater/src/NsisUpdater.ts index cc79c6ab02b..f537ee78070 100644 --- a/packages/electron-updater/src/NsisUpdater.ts +++ b/packages/electron-updater/src/NsisUpdater.ts @@ -4,7 +4,7 @@ import { tmpdir } from "os" import { download, DownloadOptions } from "electron-builder-http" import { DOWNLOAD_PROGRESS, FileInfo } from "./api" import { BintrayOptions, PublishConfiguration, GithubOptions, VersionInfo } from "electron-builder-http/out/publishOptions" -import { mkdtemp } from "fs-extra-p" +import { mkdtemp, remove } from "fs-extra-p" import "source-map-support/register" import { AppUpdater } from "./AppUpdater" @@ -34,24 +34,32 @@ export class NsisUpdater extends AppUpdater { downloadOptions.sha2 = fileInfo.sha2 } - return mkdtemp(`${path.join(tmpdir(), "up")}-`) - .then(it => download(fileInfo.url, path.join(it, fileInfo.name), downloadOptions)) - .then(it => { - this.setupPath = it - this.addQuitHandler() - const version = this.versionInfo!.version - if (this.logger != null) { - this.logger.info(`New version ${version} has been downloaded`) - } - this.emit("update-downloaded", this.versionInfo, null, version, null, null, () => { - this.quitAndInstall() - }) - return it - }) - .catch(e => { - this.emit("error", e, (e.stack || e).toString()) - throw e - }) + const logger = this.logger + const tempDir = await mkdtemp(`${path.join(tmpdir(), "up")}-`) + const tempFile = path.join(tempDir, fileInfo.name) + try { + await download(fileInfo.url, tempFile, downloadOptions) + } + catch (e) { + try { + await remove(tempDir) + } + catch (ignored) { + // ignored + } + + throw e + } + + const version = this.versionInfo!.version + if (logger != null) { + logger.info(`New version ${version} has been downloaded to ${tempFile}`) + } + + this.setupPath = tempFile + this.addQuitHandler() + this.emit("update-downloaded", this.versionInfo, null, version) + return tempFile } private addQuitHandler() { @@ -62,6 +70,9 @@ export class NsisUpdater extends AppUpdater { this.quitHandlerAdded = true this.app.on("quit", () => { + if (this.logger != null) { + this.logger.info("Auto install update on quit") + } this.install(true) }) } @@ -91,10 +102,35 @@ export class NsisUpdater extends AppUpdater { if (isSilent) { args.push("/S") } - spawn(setupPath, args, { + const spawnOptions = { detached: true, stdio: "ignore", - }).unref() + } + + try { + spawn(setupPath, args, spawnOptions) + .unref() + } + catch (e) { + // yes, such errors dispatched not as error event + // https://github.com/electron-userland/electron-builder/issues/1129 + if ((e).code === "UNKNOWN") { + if (this.logger != null) { + this.logger.info("UNKNOWN error code on spawn, will be executed again using elevate") + } + + try { + spawn(path.join(process.resourcesPath, "elevate.exe"), [setupPath].concat(args), spawnOptions) + .unref() + } + catch (e) { + this.dispatchError(e) + } + } + else { + this.dispatchError(e) + } + } return true } diff --git a/yarn.lock b/yarn.lock index 1b34932551b..5c8cbfda4b7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -41,8 +41,8 @@ resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.5.29.tgz#29f4dd9314fbccb080d8bd84b9c23811ec5090c2" "@types/node@*": - version "7.0.3" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.3.tgz#6bc1d23929bd426eabd409b5898537076bbbdeff" + version "7.0.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.4.tgz#9aabc135979ded383325749f508894c662948c8b" "@types/source-map-support@^0.2.28": version "0.2.28"