Electron-vue开发实战 - 自动更新

2,230 阅读2分钟

electron-builder构建的应用自动更新可以使用electron-updater很快的实现版本的自动更新.

使用

安装

npm i electron-updater

package.json中加入publish和版本更新信息

{
  	 "version": "0.5.18",
     ...
     "build": {
        "releaseInfo": {
      			 "releaseNotes": "1.添加了 xxxx\n2.更新了xxxx\n3.修复了 xxxx"
    			},
         "publish": [{
             "provider": "generic",
             "url": "http://***/download/"
         }],
         ...
     }
 }

打包应用

​ 在打包成功之后,在文件夹中会出现一个新latest.yml,里面保存着版本信息,如果是macOS打包后则是latest-mac.yml,在打包之后将安装包和latest.yml上传到上面的url地址下.

version: 0.5.21
files:
  - url: App Setup 0.5.21.exe
    sha512: FJZW2zwEwVYkeUMcl0JFV/7KBsf3eOU2EJ4xSuL5M4RS4Lhtd87lz2puDQ0+J/zGQNgLGAsoOlQrSOc1SrY9Nw==
    size: 46862682
path: App Setup 0.5.21.exe
sha512: FJZW2zwEwVYkeUMcl0JFV/7KBsf3eOU2EJ4xSuL5M4RS4Lhtd87lz2puDQ0+J/zGQNgLGAsoOlQrSOc1SrY9Nw==
releaseNotes: |-
  1.添加了 xxxx
  2.更新了 xxxx
  3.修复了 xxxx
releaseDate: '2020-05-21T05:11:49.180Z'

检查自动更新

  1. uoloader.js

    import axios from 'axios'
    import jsyaml from 'js-yaml'
    import pkg from '../../../package.json'
    import { dialog, shell } from 'electron'
    import { autoUpdater } from 'electron-updater'
    const version = pkg.version
    const OS = require('os').platform()
    const release = 'http://***/download/latest.yml'
    
    const checkVersion = async () => {
        const res = await axios.get(release)
    
        if (res.status === 200) {
            let data = JSON.parse(toJson(res.data))
            let latestVersion = data.version
            const macDownloadUrl = 'http://***/download/App-' + latestVersion + '.dmg'
            // const winDownloadUrl = 'http://***/download/App Setup ' + latestVersion + '.exe'
            const result = compareVersion2Update(version, latestVersion)
            let message = '发现新版本' + latestVersion + ',更新了以下功能:\n' + data.releaseNotes
            if (OS == 'darwin') {
                message = message + '\n是否去下载最新的版本?'
            } else {
                message = message + '\n是否立马自动更新?'
            }
    
            if (result) {
                dialog.showMessageBox({
                    type: 'info',
                    title: '发现新版本',
                    buttons: ['Yes', 'No'],
                    message: message,
                }, (res, checkboxChecked) => {
                    if (res === 0) { // if selected yes
                        if (OS == 'darwin') {
                            shell.openExternal(macDownloadUrl)
                        } else {
                            // shell.openExternal(winDownloadUrl)
                            autoUpdater.on('update-downloaded', () => {
                                autoUpdater.quitAndInstall()
                            })
                            autoUpdater.checkForUpdates()
                        }
                    }
                })
            }
        }
    }
    // 利用 `js-yaml` 将yaml转为 json 格式
    const toJson = function (yaml) {
        if (yaml) {
            try {
                let json = JSON.stringify(jsyaml.load(yaml), null, 2);
                return json
            } catch (e) {
                console.log(e)
            }
        }
    }
    // if true -> update else return false
    const compareVersion2Update = (current, latest) => {
        const currentVersion = current.split('.').map(item => parseInt(item))
        const latestVersion = latest.split('.').map(item => parseInt(item))
        let flag = false
    
        for (let i = 0; i < 3; i++) {
            if (currentVersion[i] < latestVersion[i]) {
                flag = true
            }
        }
    
        return flag
    }
    
    export default checkVersion
    
    1. main/index.js中引入
    // ...
    import uploader from './utils/uploader.js'
    
    app.on('ready', () => {
      // ...
      uploader()
      createWindow()
      // ...
    })
    
    1. 示例

      当检查到新版本时,就会弹出如下窗口

总结

​ 其实electron-updater自带检查版本更新功能,但是因为macOS自动更新需要对打包应用进行签名和公证,所以只好自己检查是否需要更新.

​ 如果需要对window上的下载进度进行监听,则可以加入下列代码.

// 更新下载进度事件
  autoUpdater.on('download-progress', function (progressObj) {
    mainWindow.webContents.send('downloadProgress', progressObj)
  })

参考链接:Electron-vue开发实战4——通过CI发布以及更新的方式