Electron 自动更新

1. 安装 electron-updater

npm i electron-updater --save-dev

2. 在package.json中

"build": {
    // ...
    "win": {
      "icon": "build/icons/icon.ico",
      "asar": false,
      "artifactName": "${productName}_${version}.${ext}"
    },
    "publish": [
      {
        "provider": "generic",
        "url": "http://127.0.0.1:8080" // 你的远程服务器更新文件地址,暂时用本地服务模拟
      }
    ],
    "releaseInfo": {
      "releaseNotes": "" // 更新的内容,可不填
    }
  }

3. update.js

import {autoUpdater} from 'electron-updater'
import { ipcMain } from 'electron'

// 开始检查更新
ipcMain.on('checkForUpdates', () => autoUpdater.checkForUpdates())

// 开始下载更新
ipcMain.on('downLoadUpdate', () => autoUpdater.downloadUpdate())

const updateHandle = (mainWindow, updateURL) => {
    const webContents = mainWindow.webContents
    const statusMessage = {
        error: {status: -1, msg: '检测更新查询异常'},
        checking: {status: 0, msg: '正在检查应用程序更新'},
        updateAva: {status: 1, msg: '检测到新版本,正在下载,请稍后'},
        updateNotAva: {status: 2, msg: '您现在使用的版本为最新版本,无需更新!'},
        downloadSuccess: {status: 2, msg: '下载新版成功'}
    }

    autoUpdater.autoDownload = false  // 手动指定下载
    autoUpdater.setFeedURL(updateURL)   // 更新包的地址,如 https://xxx.com/app/

    //执行自动更新检查
    // autoUpdater.checkForUpdates()

    //更新错误
    autoUpdater.on('error', error => {
        console.log(error)
        webContents.send('uploadMessage', {payload: statusMessage.error, output: error})
    })

    //检查中
    autoUpdater.on('checking-for-update', v => {
        console.log('检查中')
        webContents.send('uploadMessage', {payload: statusMessage.checking, output: v})
    })

    //发现新版本
    autoUpdater.on('update-available', info => {
        console.log('发现新版本')
        webContents.send('uploadMessage', {payload: statusMessage.updateAva, output: info})
    })

    //当前版本为最新版本
    autoUpdater.on('update-not-available', info => {
        console.log('当前版本为最新版本')
        webContents.send('uploadMessage', {payload: statusMessage.updateNotAva, output: info})
    })

    // 更新下载进度事件
    autoUpdater.on('download-progress', progress => webContents.send('downloadProgress', progress))

    // 当下载完更新包后触发
    autoUpdater.on('update-downloaded', info => {
        webContents.send('uploadMessage', {payload: statusMessage.downloadSuccess, output: info})
        autoUpdater.quitAndInstall()
    })
}


export default updateHandle

4. main进程中

const packInfo = require('../../package.json')
const [publish] = packInfo.build.publish


import updateHandle from './update'

// ....略
// createWindow时候
updateHandle(mainWindow, publish.url)

5. 渲染进程中(vue)

<template>
  <el-dialog
      style="pointer-events: none"
      :center="true"
      title="版本正在更新,请稍候..."
      :visible.sync="visible"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :show-close="false"
  >
    <div>
      <el-progress
          :text-inside="true"
          :stroke-width="24"
          :percentage="percentage"
          :show-text="true"
      />
    </div>
  </el-dialog>
</template>

<script>
const {ipcRenderer} = require('electron')

export default {
  name: "AutoUpdate",
  data() {
    return {
      visible: false,
      percentage: 0
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    init() {
      ipcRenderer.send('checkForUpdates')
      ipcRenderer.on('uploadMessage', (event, args) => {
        console.log(args)
        const {payload} = args
        const {msg, status} = payload
        const handle = {
          '-1': () => {
            this.$message.error(msg)
          },
          '0': () => {
            this.$message.info(msg)
            /*正在检测更新*/
          },
          '1': () => {
            this.$message.info(msg)
            /* 发送下载请求 */
            ipcRenderer.send('downLoadUpdate')
            this.visible = true
          },
          '2': () => {
            this.$message.info(msg)
            /*当前为最新版本*/
          },
          '3':() => {
            this.$message.success(msg)
          }
        }
        handle[`${status}`].call(this)
      })

      ipcRenderer.on('downloadProgress', (event, data) => {
        const {percent} = data
        this.percentage = Number.parseFloat((percent || 0).toFixed(2))
        if (percent >= 100) this.visible = false
      })
    }
  }
}
</script>

6. 测试

使用node静态托管,nginx也可以

const express = require('express')
const app = express()

//设置跨域访问
app.all('*', (req, res, next) => {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
    res.header("X-Powered-By",' 3.2.1')
    res.header("Content-Type", "application/json;charset=utf-8");
    next()
})

app.use(express.static('D:/work/code/electron-print-web/build')) // 此处为打包后生成文件的绝对路径

const server = app.listen(8080, 'localhost', () => {
    const host = server.address().address
    const port = server.address().port
    console.log('Example app listening at http://%s:%s', host, port)
})
  • 每次打包前去修改package.json中的version,打包完成后重启已安装的低版本程序,程序启动后会自动更新至新版本
posted @ 2021-03-03 14:41  demo_you  阅读(804)  评论(4编辑  收藏  举报