使用electron-updater实现客户端更新

使用electron-updater实现客户端更新

Scroll Down

框架说明

在electron中使用vue技术栈可以和react一样方便,也提供了一个便利的打包插件:vue-cli-plugin-electron-builder,安装以后无需再另装electron-builder模块。

# yarn add vue-cli-plugin-electron-builder --dev

使用electron-updater

1.安装模块

要使用electron的自动更新功能,首先需要安装对应功能模块。

# yarn add electron-updater
# yarn add electron-log  // 辅助功能,写LOG到文件

2.Main端代码

安装vue-cli-plugin-electron-builder后,插件会自动在src目录下生成background.js文件,用户可以在这里控制main端的行为。

我们在这里新建update.js,定义控制更新行为的代码。


import { autoUpdater } from 'electron-updater';
import { ipcMain } from 'electron';
import Constants from './Constants';
import log from 'electron-log';

let mainWindow = null;

export function handleUpdate(window) {

  mainWindow = window;

  // 设置更新包地址
  autoUpdater.setFeedURL(Constants.UPDATE_URL);
  autoUpdater.autoDownload = false;

  // 升级失败
  autoUpdater.on('error', error => {
    log.error('升级过程出错', error);
    sendMessage2Render({ cmd: Constants.UpdateCmd.ERROR });
  });

  // 开始检查更新
  autoUpdater.on('checking-for-update', message => {
    log.info('应用更新 - 开始检查服务端信息');
    sendMessage2Render({ cmd: Constants.UpdateCmd.CHECKING });
  });

  // 检查到有可用更新
  autoUpdater.on('update-available', message => {
    log.info('应用更新 - 有可用更新');
    sendMessage2Render({ cmd: Constants.UpdateCmd.AVAILABLE });
  });

  // 检查到无可用更新
  autoUpdater.on('update-not-available', message => {
    log.info('应用更新 - 无可用更新');
    sendMessage2Render({ cmd: Constants.UpdateCmd.NO_AVAILABLE });
  });

  // 更新下载进度
  autoUpdater.on('download-progress', progressObj => {
    log.info('应用更新 - 取得下载进度', progressObj);
    sendMessage2Render({ cmd: Constants.UpdateCmd.DOWNLOADING, message: progressObj });
  });

  // 下载完成通知
  autoUpdater.on('update-downloaded', (event, notes, name, date, url) => {
    log.info('应用更新 - 更新包已下载完成');
    sendMessage2Render({ 
      cmd: Constants.UpdateCmd.DOWNLOADED,
      message: { notes, name, date, url }
    });
  });

  // 接收渲染层命令,开始检查更新
  ipcMain.on('checkForUpdate', (e, arg) => {
    log.info('应用更新 - 收到检查更新命令');
    autoUpdater.checkForUpdates();
  });

  // 接收渲染层命令,开始下载
  ipcMain.on('download', (e, arg) => {
    log.info('应用更新 - 收到下载更新包命令');
    autoUpdater.downloadUpdate();
  });

  // 接收渲染层命令,退出并安装
  ipcMain.on('quitAndInstall', (e, arg) => {
    log.info('应用更新 - 收到退出并安装命令');
    autoUpdater.quitAndInstall();
  });
}

/**
 * 发送消息到渲染层
 * @param {*}} text 
 */
function sendMessage2Render(text) {
  mainWindow.webContents.send('message', text);
}

在Constants文件中,定义了自动更新过程中的几个关键事件名称,而UPDATE_URL则定义了要从哪里去取得更新包信息。

export default {

  UPDATE_URL: 'http://192.168.1.108/',

  ...

  UpdateCmd: {
    ERROR: 1,
    CHECKING: 2,
    AVAILABLE: 3,
    NO_AVAILABLE: 4,
    DOWNLOADING: 5,
    DOWNLOADED: 6
  },

  ...
}

最后,在background.js中引入update.js,在窗口初始化后传入窗口对象即可。


...
import { handleUpdate } from './autoUpdate';

let win = null;
function createWindow() {

  win = new BrowserWindow({ ... });

  ...

  // 准备自动更新的处理
  handleUpdate(win);
}
...

3.准备打包

使用了vue-cli-plugin-electron-builder后,打包变得非常方便,仅仅需要一下命令:

# yarn electron:build

对于electron-updater的更新功能来讲,还需要多一个步骤。网络上很多资料都提到要加上publish的相关说明:

// package.json
{
  ...
  "publish": [
    {
      "provider": "generic",
      "url": "http://192.168.1.108:5000/"
    }
  ],
  ...
}

加入后执行打包命令,就会在打包路径下自动生成xxx.yml,这个文件用来描述当前的更新文件信息。但我试过多次都没有效果,包括在publish上再加一层build字段。

后来终于在vue-cli-plugin-electron-builder的官方文档中查阅到,publish信息需要写道vue.config.js中,插件会自动读取。

module.exports = {
  css: {
    loaderOptions: {
      less: {
        lessOptions: {
          javascriptEnabled: true,
        }
      }
    }
  },
  pluginOptions: {
    electronBuilder: {
      nodeIntegration: true,    // 使得Node模块可以使用
      builderOptions: {         // 定义编译选项
        "publish": [
          {
            "provider": "generic",
            "url": "http://192.168.1.108:5000/"
          }
        ],
      }
    }
  }
}

打包并部署

修改应用版本号

应用的版本号在package.json中的version字段进行修改。

{
  "name": "my-app",
  "version": "1.0.0",
  ...
}

当electron-updater检查到更高的版本号对应安装文件存在时,将会下载并进行安装。版本号遵循semver的规则进行管理。

执行打包

命令很简单。

# yarn electron:build

命令执行完成后,会在dist_electron目录下出现对应打包好的文件。

- dist_electron
  - my-app-1.0.0.exe
  - latest-mac.yml      // Windows和Linux环境有类似的yml描述文件

将文件部署到之前描述的存放新版本文件的目录下即可。