Electron~增量更新和全量更新

增量更新说明文档

  • 增量更新指的是本地发布前通过打包生成dist,压缩成app.zip包,上传到服务器;客户端每次重启执行一次检测更新,比较本地与远程json的版本,如果有最新版本,则获取zip包并解压覆盖到本地,重启app完成更新;

English Version

update

提前准备

  1. 准备本地或者远程服务器或者远程静态文件url
npm i -g http-server
cd yourFileFolder // 进入任意文件夹
http-server -p 4000 // 快速开启本地服务,用于存储更新文件
  1. 配置和打包,拿到更新文件内容并压缩
// package.json
// 关闭asar模式
  "asar": false,
// 打包
  npm run pack-windows
// 进入打好的windows包
  cd release\0.x.x_setup\win-unpacked\resources
// 压缩app文件夹 => app.zip, 拷贝app-update.yml和app.zip

  1. app.zip app-update.yml 传到服务器

  2. 本地流程,启动客户端,点击增量更新

// 入口
// src\render\components\AutoUpdate\index.tsx
 <Button type='primary' onClick={() => checkForPartUpdates()} style={{ marginLeft: 10 }}>
            增量更新
        </Button>

// 本地检查与服务器的version版本比较
// 如果找到新版本,则向主进程通信,通知checkForPartUpdates开始更新

// src\render\utils\autoUpdate\partUpdate.js
/** 检查更新 */
export async function checkForPartUpdates() {
  try {
    // check version 检查版本
    const res = await checkVersion()
    if (res && res === 'OPEN_PART_UPDATE') {
      // 增量更新
      console.log('OPEN_PART_UPDATE')
      confirm({
        title: '检测到更新',
        icon: <ExclamationCircleOutlined />,
        content: (
          <div>
            <p>是否更新?</p>
          </div>
        ),
        okText: '确认',
        cancelText: '取消',
        onOk() {
          ipc && ipc.send('checkForPartUpdates')
          message.info('请耐心等待几秒..')
        },
        onCancel() {
          console.log('Cancel');
        },
      });
      // partUpdates()
    }
    if (res && res === 'OPEN_ALL_UPDATE') {
      console.log('OPEN_ALL_UPDATE')
      // 全量更新
    }
  } catch (error) {
    console.error('checkVersionERROR', error)
  }
}

function checkVersion(params) {
  return new Promise((resolve, reject) => {
    const currentVersion = remote.app.getVersion()
    // 获取最新版本号
    downloadFile(remoteYmlURL, localYmlUrl).then(res => {
      const remoteVersion = JSON.stringify(res.data).split('\\n')[0].split(' ')[1]
      const remoteVersionArr = remoteVersion.split('.')
      const currentVersionArr = currentVersion.split('.')
      // 0.1.1 Y和Z比较来开启增量更新  1.1.1 X比较来开启全量更新
      if (Number(remoteVersionArr[0]) > Number(currentVersionArr[0])) {
        // 开启全量更新
        return resolve('OPEN_ALL_UPDATE')
      } else if (Number(remoteVersionArr[2]) > Number(currentVersionArr[2]) || Number(remoteVersionArr[1]) > Number(currentVersionArr[1])) {
        // 开启增量更新
        return resolve('OPEN_PART_UPDATE')
      } else {
        console.log('无版本变动,不更新')
      }
    }).catch(e => {
      console.error(e)
    })
  })
}

// src\main\controls\AppAutoUpdater.js
// 下载服务器文件包
// 本地解压和备份,替换,重启客户端即可完成更新

  // 增量更新
  ipcMain.on('checkForPartUpdates', async (e, msg) => {
    console.log('checkForPartUpdates', msg)
    // if (isElectronDev) {
    //   console.log('开发模式不支持')
    //   return
    // }
    try {
      if (fs.existsSync(`${localresourcePath}.back`)) { // 删除旧备份
        deleteDirSync(`${localresourcePath}.back`)
      }
      if (fs.existsSync(localresourcePath)) {
        fs.renameSync(localresourcePath, `${localresourcePath}.back`); // 备份目录
      }
      await downloadFile(remoteAppURL, appZipPath)
      console.log('app.asar.unpacked.zip 下载完成')
      fs.mkdirSync(localresourcePath) // 创建app来解压用
      try {
        // 同步解压缩
        const unzip = new AdmZip(appZipPath)
        unzip.extractAllTo(resourcePath, true)
        console.log('app.asar.unpacked.zip 解压缩完成')
        console.log('更新完成,正在重启...')
        mainWindow.webContents.send('partUpdateReady')
        setTimeout(() => {
          app.relaunch(); // 重启
          app.exit(0);
        }, 1800);
      } catch (error) {
        console.error(`extractAllToERROR: ${error}`);
      }
      // 更新窗口
      // BrowserWindow.getAllWindows().forEach((win: any) => {
      //   win.webContents.reload()
      //   // remote.app.relaunch(); // 重启
      //   // remote.app.exit(0);
      // })
      console.log('webContents reload完成')
    } catch (error) {
      console.error(`checkForPartUpdatesERROR`, error)
      if (fs.existsSync(`${localresourcePath}.back`)) {
        fs.renameSync(`${localresourcePath}.back`, localresourcePath);
      }
    }
  })

github

全量更新

  • 全量更新指的是下载服务器最新包覆盖安装更新;
  1. 目前使用的三方库是electron-updater,主要api是checkForUpdatesAndNotify, autoUpdater类 监听下载进度,检查更新等,
  2. app主进程接收updater信息,并与渲染进程通信,下载进度发送到渲染进程,渲染进程展示

update

posted @ 2020-07-31 21:32  枫叶丶|  阅读(6320)  评论(3编辑  收藏  举报