🐱‍🐉Electron-🐱‍🏍远程更新-🐱‍👤electron-updater-🎉全量更新🤳

597 阅读3分钟

准备

//引入electron-updater
npm i electron-updater -D//好像是这个

实现

主进程

实现文件

新建的updater.js文件

//#updater.js
const { ipcMain, Notification } = require('electron')
const { autoUpdater } = require('electron-updater')
//const config = require('./config.js')

// 初始化更新模块-监听
ipcMain.on("downLoadInit", (event) => {
    listenUpdater(event)
})

// 开始检查更新-监听    接收到渲染进程来的讯息后检测更新
ipcMain.on("downloadSee", () => {
    autoUpdater.checkForUpdates()
})

// 开始下载更新-监听
ipcMain.on("downLoadUpdate", () => {
    fnNotification('新版本下载中,请等待')
    autoUpdater.downloadUpdate()//开始下载,注意:下载后如果不更新,可能会导致下次打开异常,所有下载更新一体
})

/**
 * 初始化更新模块
 * @param {*} event 
 */
const listenUpdater = (event) => {//event 内部方法用作消息广播,也可用main调用,传递win过来(获取send方法)

    autoUpdater.autoDownload = false  // 手动指定下载
    //let url = config.UPDATE_URL
    let url = 'http://XXXX/app/'//更改为版本库地址,测试时可以在本地跑一个web服务
    autoUpdater.setFeedURL(url)   // 更新包的地址

    //异常捕获回调
    autoUpdater.on('error', function (error) {
        event.sender.send("checkUpdateError", JSON.stringify(error))
    })

    // 检查更新中
    autoUpdater.on('checking-for-update', function () {
        //event.sender.send("msgUpdater", '检查更新中')
    })

    // 检测到有新版本更新
    autoUpdater.on('update-available', function (info) {
        event.sender.send("update-available", JSON.stringify(info))
    })

    // 暂无新版本可更新
    autoUpdater.on('update-not-available', function (info) {
        event.sender.send("update-not-available", JSON.stringify(info))
    })

    // 更新下载进度事件
    autoUpdater.on('download-progress', function (progressObj) {
        event.sender.send("download-progress", JSON.stringify(progressObj))
    })

    // 下载完成,退出且重新安装
    autoUpdater.on('update-downloaded', function () {
        fnNotification('下载完成,正在重新安装')
        autoUpdater.quitAndInstall()//退出且重新安装
    })
}

//实现系统提示的方法(屏幕右下角弹窗提示)
const fnNotification = (title) => {
    setTimeout(() => {
        let NOTIFICATION_BODY = new Date().toLocaleTimeString()
        let data = { title: title, body: NOTIFICATION_BODY }
        try {
            let thisNotification = new Notification(data)
            thisNotification.show()
        } catch (error) {
            console.log(error);
        }
    }, 1000)
}

main.js引入

//#main.js
require('./updater.js')
//如果是接收自渲染进程消息再初始化,可以只执行,也可以暴露初始化方法到main.js执行并传入win对象(获取send方法)

渲染进程

下面是查询和更新分离的实现,具体页面逻辑根据实际情况实现

//#renew.ts
import { ipcRenderer } from 'electron'

//初始化
ipcRenderer.send("downLoadInit")//也可以直接在主进程初始化

//查询版本
export const onRenewSeeFn = () => {
    ipcRenderer.send("downloadSee")
}

//下载并更新
export const onRenewGoFn = () => {
    ipcRenderer.send("downLoadUpdate")
}

//--------------------------------------------------------------消息监听

//版本检测异常
ipcRenderer.on("checkUpdateError", (event, data) => {
    let msg = '版本检测异常'
    // ......
})

// 检测到有新版本更新
ipcRenderer.on("update-available", (event, data) => {
    data = JSON.parse(data)
    // ......
})

// 暂无新版本可更新
ipcRenderer.on("update-not-available", (event, data) => {
    data = JSON.parse(data)
    // ......
})

// 更新下载进度事件
ipcRenderer.on("download-progress", (event, data) => {
    data = JSON.parse(data)
    // ......
})

package.json配置

打包时将文件添加致版本库(我这里没起效果,所以是手动上传到服务器的)

"publish": [
      {
        "provider": "generic",
        "url": "http://XXXX/app/"
      }
    ],

附加build打包配置

"build": {
    "appId": "XXXapp",
    "productName": "XXXapp",
    "asar": false,
    "copyright": "Copyright © 2022 electron",
    "directories": {
      "output": "release/"
    },
    "files": [
      "_electron_/**/*",
      "dist/**/*"
    ],
    "mac": {
      "artifactName": "${productName}_${version}.${ext}",
      "target": [
        "dmg"
      ]
    },
    "win": {
      "icon": "/public/icon.png",
      "target": [
        {
          "target": "nsis",
          "arch": [
            "x64"
          ]
        }
      ],
      "artifactName": "${productName}_${version}.${ext}"
    },
    "nsis": {
      "artifactName": "${productName}_${version}.${ext}",
      "uninstallDisplayName": "SC",
      "oneClick": false,
      "allowToChangeInstallationDirectory": true,
      "createDesktopShortcut": true,
      "createStartMenuShortcut": true,
      "runAfterFinish": true,
      "installerLanguages": [
        "zh_CN"
      ]
    },
    "electronDownload": {
      "mirror": "https://npm.taobao.org/mirrors/electron/",
      "cache": "E:/",
      "version": "23.2.0"
    },
    "publish": [
      {
        "provider": "generic",
        "url": "http://XXXX/app/"
      }
    ],
    "releaseInfo": {
      "releaseNotes": ""
    },
    "extends": null
  }

版本库文件

需要下面两个文件

//文件1   版本信息
latest.yml
//文件2   版本文件(我这里是全量更新)
XXXapp.exe可执行文件

add

const { Notification } = require('electron')
const { autoUpdater } = require('electron-updater')
const config = require('./config.js')


autoUpdater.autoDownload = false  // 手动指定下载
autoUpdater.setFeedURL(config.UPDATE_URL)   // 更新包的地址
autoUpdater.checkForUpdates()

//异常
autoUpdater.on('error', function (error) { })
// 检查更新中
autoUpdater.on('checking-for-update', function () { })
// 暂无新版本可更新
autoUpdater.on('update-not-available', function (info) { })
// 更新下载进度事件
autoUpdater.on('download-progress', function (progressObj) { })


// 检测到有新版本更新
autoUpdater.on('update-available', function (info) {
    autoUpdater.downloadUpdate()//更新
})

// 下载完成,退出且重新安装
autoUpdater.on('update-downloaded', function () {
    fnNotification('有新版本内容,即将更新并重启')
    setTimeout(() => {
        autoUpdater.quitAndInstall()//退出且重新安装
    }, 3000)
})


const fnNotification = (title) => {
    setTimeout(() => {
        let NOTIFICATION_BODY = new Date().toLocaleTimeString()
        let data = { title: title, body: NOTIFICATION_BODY }
        try {
            let thisNotification = new Notification(data)
            thisNotification.show()
        } catch (error) {
        }
    }, 1000)
}