Update needs to prompt the user, need to control whether the application updates

1. One way

Prompts the user when an update is detected, allowing the user to select an update.

Set the autoDownload parameter to false so that the application detects that updates do not automatically download and changes to manually download updates.

Add a dialog to prompt the user to select the hook update-available.

If response is 0, the user selects yes and the downloadUpdate method is triggered to download the application update package for subsequent update operations. Otherwise, do not download the update package.

If we don’t set autoDownload to false, the problem is that the app downloads automatically and updates without blocking while the dialog pops up before the user has time to select it.

This article was first published on the public account “Full stack big guy’s Cultivation road”, welcome to follow.

The important code is as follows:

autoUpdater.autoDownload = false
Copy the code

A dialog box pops up in the update-available hook

autoUpdater.on('update-available'.(ev, info) = > {
  // // irreversible process
  const options = {
    type: 'info'.buttons: ['sure'.'cancel'].title: 'Update Prompt'.// ${info.version} Cannot read property 'version' of undefined
    message: 'New version found. Update? '.cancelId: 1
  }
  dialog.showMessageBox(options).then(res= > {
    if (res.response === 0) {
      autoUpdater.downloadUpdate()
      logger.info('Update package downloaded successfully')
      sendStatusToWindow('Update package downloaded successfully');
    } else {
      return; }})})Copy the code

2. 2

Prompt the user after the update download, let the user choose to update.

Set the autoInstallOnAppQuit parameter to false to prevent the application from automatically updating when an update package is detected.

Add a dialog in the hook update-downloaded to prompt the user to choose.

If response is 0, the user selects YES and updates the application. Otherwise, the current application is not updated.

If we don’t set autoInstallOnAppQuit to false, then the problem is: the first time we open the app, the app closes immediately before we see the main screen, the app updates silently, and the important thing is not to restart the app after the update.

The important code is as follows:

// Indicates that the downloaded package is not automatically updated
autoUpdater.autoInstallOnAppQuit = falseIn the update-downloaded hook, the autoupdater. on('update-downloaded'.(ev, releaseNotes, releaseName) = > {
  logger.info('Download complete, update started')
  sendStatusToWindow('Download complete, update started');
  // Wait 5 seconds, then quit and install
  // In your application, you don't need to wait 5 seconds.
  // You could call autoUpdater.quitAndInstall(); immediately
  const options = {
    type: 'info'.buttons: ['sure'.'cancel'].title: 'Apply updates'.message: process.platform === 'win32' ? releaseNotes : releaseName,
    detail: 'New version found. Update? '
  }
  dialog.showMessageBox(options).then(returnVal= > {
    if (returnVal.response === 0) {
      logger.info('Start updating')
      setTimeout(() = > {
        autoUpdater.quitAndInstall()
      }, 5000);
    } else {
      logger.info('Cancel update')
      return}})});Copy the code

3. Source code analysis

Not pack directory in: electron – builder/packages/electron – updater/SRC/AppUpdater ts. Pack it in the electron-updater\out\AppUpdater. D. ts

  1. Start by going to the checkForUpdates() method and checking for updates
  2. Updating does not require entry
  3. Check autoDownload before update. If it is true, autoDownload is automatically downloaded; if it is false, do not download and wait for application notification.
export declare abstract class AppUpdater extends EventEmitter {
    /** * Whether to automatically download the update when an update is detected * scenario: This can be applied to the electron check for the update package prompt and whether the update is required for user operations */
    autoDownload: boolean;
    /** * Whether to automatically update the downloaded update package after app.quit() * Scenario: This can be applied to the prompt after the electron download of the update package, and whether the user needs to update the update package. When you open an app the second time, it doesn't update automatically. * /
    autoInstallOnAppQuit: boolean;
}


/** * checks whether an update is required */
checkForUpdates(): Promise < UpdateCheckResult > {
  let checkForUpdatesPromise = this.checkForUpdatesPromise
  // Checking for update skipped
  if(checkForUpdatesPromise ! =null) {
    this._logger.info("Checking for update (already in progress)")
    return checkForUpdatesPromise
  }

  const nullizePromise = () = > this.checkForUpdatesPromise = null
  // Start checking for updates
  this._logger.info("Checking for update")
  checkForUpdatesPromise = this.doCheckForUpdates()
  .then(it= > {
    nullizePromise()
    return it
  })
  .catch(e= > {
    nullizePromise()
    this.emit("error", e, `Cannot check for updates: ${(e.stack || e).toString()}`)
    throw e
  })

  this.checkForUpdatesPromise = checkForUpdatesPromise
  return checkForUpdatesPromise
}
// Check to update the specific function
private async doCheckForUpdates(): Promise < UpdateCheckResult > {
  // Triggers the checking-for-update hook
  this.emit("checking-for-update")
  // Get the update information
  const result = await this.getUpdateInfoAndProvider()
  const updateInfo = result.info
  // Check whether the updated information is valid
  if (!await this.isUpdateAvailable(updateInfo)) {
    this._logger.info(`Update for version The ${this.currentVersion} is not available (latest version: ${updateInfo.version}, downgrade is The ${this.allowDowngrade ? "allowed" : "disallowed"}). `)
    this.emit("update-not-available", updateInfo)
    return {
      versionInfo: updateInfo,
      updateInfo,
    }
  }

  this.updateInfoAndProvider = result
  this.onUpdateAvailable(updateInfo)

  const cancellationToken = new CancellationToken()
  //noinspection ES6MissingAwait
  // If autoDownload is set to true, the update package will be automatically downloaded; otherwise, it will not be downloaded
  return {
    versionInfo: updateInfo,
    updateInfo,
    cancellationToken,
    downloadPromise: this.autoDownload ? this.downloadUpdate(cancellationToken) : null}}Copy the code

If you need to configure other parameters in the Updater to perform certain functions, you can take a closer look at the configuration items.

export abstract class AppUpdater extends EventEmitter {
    /** * Whether to automatically download the update when an update is detected * scenario: This can be applied to the electron check for the update package prompt and whether the update is required for user operations */
    autoDownload: boolean;
    /** * Whether to automatically update the downloaded update package after app.quit() * Scenario: This can be applied to the prompt after the electron download of the update package, and whether the user needs to update the update package. When you open an app the second time, it doesn't update automatically. * /
    autoInstallOnAppQuit: boolean;
    /** * GitHub provider. Whether to allow upgrades to pre-release versions. The default is "true" if the application version contains pre-release components. 0.12.1-alpha.1, where alpha is a pre-release component), otherwise "false". AllowDowngrade set to true, allowDowngrade will be applied. * /
    allowPrerelease: boolean;
    /** * GitHub provider. Get all release notes (from the current version to the latest version), not just the latest version.@default false* /
    fullChangelog: boolean;
    /** * Whether to allow version degradation (when the user from the test channel wants to return to the stable channel). * Only if the channel is not considered at the same time (pre-release components controlled by semantic versioning). *@default false* /
    allowDowngrade: boolean;
    /** * Current application version */
    readonly currentVersion: SemVer;
    private _channel;
    protected downloadedUpdateHelper: DownloadedUpdateHelper | null;
    /** * get the update channel. Does not apply to GitHub. "Channel" is not returned from the updated configuration, only if previously set. * /
    get channel() :string | null; /** * Set the update channel. Do not apply toGitHub. Overwrite "in update configurationchannel". "allowDowngrade"Will be automatically set to"true". If the behavior doesn't suit you, specify and simply set it."allowDowngrade". * /set channel(value: string | null); /** * request header */requestHeaders: OutgoingHttpHeaders | null;
    protected _logger: Logger;
    get netSession() :Session; / * * *The logger. You can pass [electron-log] (https://github.com/megahertz/electron-log), [winston](https://github.com/winstonjs/winston) or another logger with the following interface: `{ info(), warn(), error() }`.
     * Set it to `null` ifYou order like to disable a logging feature. * log, types are: info, warn, error * / get logger () : a logger |null;
    set logger(value: Logger | null);
    /** * For type safety you can use signals, e.g. For type safety, use signals. For example: ` autoUpdater. Signals. UpdateDownloaded (() = > {}) home ` ` autoUpdater. On (' update - available ', () = > {}) ` * /
    readonly signals: UpdaterSignal;
    private _appUpdateConfigPath;
    /**
     * test only
     * @private* /
    set updateConfigPath(value: string | null);
    private clientPromise;
    protected readonly stagingUserIdPromise: Lazy<string>;
    private checkForUpdatesPromise;
    protected readonly app: AppAdapter;
    protected updateInfoAndProvider: UpdateInfoAndProvider | null;
    protected constructor(
        options: AllPublishOptions | null | undefined, app? : AppAdapter );/** * gets the current updated URL */
    getFeedURL(): string | null | undefined;
    /**
     * Configure update provider. If value is `string`, [GenericServerOptions](/configuration/publish#genericserveroptions) will be set with value as `url`.
     * @param Options If you want to override configuration in the 'app-update.yml'. * * Configures the update provider. By providing url *@param Options If you want to override the configuration in 'app-update.yml'. * /
    setFeedURL(options: PublishConfiguration | AllPublishOptions | string) :void;
    /** * Check whether the service has been updated */
    checkForUpdates(): Promise<UpdateCheckResult>;
    isUpdaterActive(): boolean;
    / * * * *@param DownloadNotification asks the server if an update is available, downloads it and notifies it if the update is available */checkForUpdatesAndNotify( downloadNotification? : DownloadNotification ):Promise<UpdateCheckResult | null>;
    private static formatDownloadNotification;
    private isStagingMatch;
    private computeFinalHeaders;
    private isUpdateAvailable;
    protected getUpdateInfoAndProvider(): Promise<UpdateInfoAndProvider>;
    private createProviderRuntimeOptions;
    private doCheckForUpdates;
    protected onUpdateAvailable(updateInfo: UpdateInfo): void;
    /** ** Action: Start downloading updates ** This method can be used if the 'autoDownload' option is set to false. * *@returns {Promise<string>} Path to downloaded file.
     */downloadUpdate(cancellationToken? : CancellationToken):Promise<any>;
    protected dispatchError(e: Error) :void;
    protected dispatchUpdateDownloaded(event: UpdateDownloadedEvent): void;
    protected abstract doDownloadUpdate(
        downloadUpdateOptions: DownloadUpdateOptions
    ): Promise<Array<string> >;/** * Effect: After downloading, restart the application and install the update. * Only called after 'update-downloads' is triggered. * * note: if the update - downloaded hook, let the user choose whether to update the application, choose not to update, it is not implemented autoUpdater. QuitAndInstall () method. * Although the application is not updated, when the application detects a local update package when it opens the application a second time, it will update the application directly and will not restart the updated application. * * To solve this problem, set 'autoInstallOnAppQuit' to false. Disable automatic application updates. * * '* * * * Note: autoUpdater. QuitAndInstall ()' will be the first to close all applications window, and then only on the 'app' a 'before - quit' event. * This is different from the normal sequence of exit events. * *@param IsSilent Only Windows runs setup in silent mode. The default is false. *@param IsForceRunAfter Can run the application after completion even without prompting for installation. Does not apply to macOS. Ignore whether isSilent is set to false. * /
    abstractquitAndInstall(isSilent? :boolean, isForceRunAfter? :boolean) :void;
    private loadUpdateConfig;
    private computeRequestHeaders;
    private getOrCreateStagingUserId;
    private getOrCreateDownloadHelper;
    protected executeDownload(
        taskOptions: DownloadExecutorTask
    ): Promise<Array<string> >; }Copy the code

Finally, I hope you must point to like three times.

More articles are in my blog address