diff --git a/packages/electron-updater/src/AppImageUpdater.ts b/packages/electron-updater/src/AppImageUpdater.ts index fcc3c0ec4ea..038b92084ca 100644 --- a/packages/electron-updater/src/AppImageUpdater.ts +++ b/packages/electron-updater/src/AppImageUpdater.ts @@ -74,7 +74,7 @@ export class AppImageUpdater extends BaseUpdater { }) } - protected doInstall(installerPath: string, isSilent: boolean, isRunAfter: boolean): boolean { + protected async doInstall(installerPath: string, isSilent: boolean, isRunAfter: boolean): Promise<boolean> { const appImageFile = process.env.APPIMAGE!! if (appImageFile == null) { throw newError("APPIMAGE env is not defined", "ERR_UPDATER_OLD_FILE_NOT_FOUND") diff --git a/packages/electron-updater/src/BaseUpdater.ts b/packages/electron-updater/src/BaseUpdater.ts index 96a33493ab2..46337961d4d 100644 --- a/packages/electron-updater/src/BaseUpdater.ts +++ b/packages/electron-updater/src/BaseUpdater.ts @@ -33,7 +33,7 @@ export abstract class BaseUpdater extends AppUpdater { }) } - protected abstract doInstall(installerPath: string, isSilent: boolean, isRunAfter: boolean): boolean + protected abstract doInstall(installerPath: string, isSilent: boolean, isRunAfter: boolean): Promise<boolean> protected async install(isSilent: boolean, isRunAfter: boolean): Promise<boolean> { if (this.quitAndInstallCalled) { @@ -54,7 +54,7 @@ export abstract class BaseUpdater extends AppUpdater { try { this._logger.info(`Install: isSilent: ${isSilent}, isRunAfter: ${isRunAfter}`) - return this.doInstall(installerPath, isSilent, isRunAfter) + return await this.doInstall(installerPath, isSilent, isRunAfter) } catch (e) { this.dispatchError(e) diff --git a/packages/electron-updater/src/NsisUpdater.ts b/packages/electron-updater/src/NsisUpdater.ts index 44aadd3e07f..690774ebdee 100644 --- a/packages/electron-updater/src/NsisUpdater.ts +++ b/packages/electron-updater/src/NsisUpdater.ts @@ -87,7 +87,7 @@ export class NsisUpdater extends BaseUpdater { return await verifySignature(Array.isArray(publisherName) ? publisherName : [publisherName], tempUpdateFile, this._logger) } - protected doInstall(installerPath: string, isSilent: boolean, isForceRunAfter: boolean): boolean { + protected async doInstall(installerPath: string, isSilent: boolean, isForceRunAfter: boolean): Promise<boolean> { const args = ["--updated"] if (isSilent) { args.push("/S") @@ -109,8 +109,7 @@ export class NsisUpdater extends BaseUpdater { } try { - spawn(installerPath, args, spawnOptions) - .unref() + await this._spawn(installerPath, args, spawnOptions) } catch (e) { // yes, such errors dispatched not as error event @@ -118,8 +117,7 @@ export class NsisUpdater extends BaseUpdater { if ((e as any).code === "UNKNOWN" || (e as any).code === "EACCES") { // Node 8 sends errors: https://nodejs.org/dist/latest-v8.x/docs/api/errors.html#errors_common_system_errors this._logger.info("Access denied or UNKNOWN error code on spawn, will be executed again using elevate") try { - spawn(path.join(process.resourcesPath!, "elevate.exe"), [installerPath].concat(args), spawnOptions) - .unref() + await this._spawn(path.join(process.resourcesPath!, "elevate.exe"), [installerPath].concat(args), spawnOptions) } catch (e) { this.dispatchError(e) @@ -133,6 +131,31 @@ export class NsisUpdater extends BaseUpdater { return true } + /** + * This handles both node 8 and node 10 way of emitting error when spawing a process + * - node 8: Throws the error + * - node 10: Emit the error(Need to listen with on) + */ + private async _spawn(exe: string, args: Array<string>, options: any) { + return new Promise((resolve, reject) => { + + try { + const process = spawn(exe, args, options) + process.on("error", error => { + reject(error) + }) + process.unref() + + if (process.pid !== undefined) { + resolve(true) + } + } catch (error) { + reject(error) + } + }) + + } + // private downloadBlockMap(provider: Provider<any>) { // await provider.getBytes(newBlockMapUrl, cancellationToken) // }