Electron的使用笔记之自动检测版本更新

使用electron-updater插件

npm install electron-updater //如果使用这种安装方式package.json的devDependencies可能会没有electron-updater

建议使用下面这种

npm install --save-dev electron-updater

注意:

(1)electron-updater的最新版本有坑,需要降低版本。

npm install --save-dev electron-updater@3.1.2

(2)安装完成之后,检查package.json的devDependencies是否有electron-updater,如若没有需要进行相关调整。

  "dependencies": {
      //其他依赖省略
      "electron-updater": "^3.1.2",        
  },
   "devDependencies": {
      //其他依赖省略
      //如果devDependencies里面没有electron-updater,需要手动复制一份
      "electron-updater": "^3.1.2",        
  },

package.json中的配置

package.json文件中,需要在build里面配置publish参数。

url:就是服务器安装包的获取地址。

{
   //其他省略
  "build": {
    "publish": [{
      "provider": "generic",
      "url": "https://xxxxxxxx/xx/xxxx/64/"
    }],
   //其他省略
  },
  "dependencies": {
      //其他依赖省略
      "electron-updater": "^3.1.2",        
  },
  "devDependencies": {
      //其他依赖省略
      //如果devDependencies里面没有electron-updater,需要手动复制一份
      "electron-updater": "^3.1.2",        
  },
}

主线程的配置

主进程的文件夹里面新建一个文件夹update.js

update.js

import { autoUpdater } from 'electron-updater';
import config from '../../package.json';
import { ipcMain } from 'electron';
let mainWindow = null;
// 直接从package.json中读取,修改package.json对应字段就可以
let feedUrl = config.build.publish[0].url; //获取在package.json里面设定的服务器安装包存放地址publish
export function updateHandle(window) {
  mainWindow = window;// 获取当前窗口
  autoUpdater.autoDownload = false; // 是否自动更新,否
  // electron-update有 bug,在本地调试时会去取electron的版本,而不是软件的版本号
  if (process.env.NODE_ENV !== 'production') {
    autoUpdater.currentVersion = config.version;
  }
  //设置更新包的地址
  autoUpdater.setFeedURL(feedUrl);
  //给渲染进程发送消息
 function sendUpdateMessage(text) {
  mainWindow.webContents.send('message', text);
 }
  //监听升级失败事件
  autoUpdater.on('error', function(error) {
    console.log('监听升级失败事件');
    sendUpdateMessage({
      cmd: 'error',
      message: error,
    });
  });
  //监听开始检测更新事件
  autoUpdater.on('checking-for-update', function(message) {
    console.log(message);
    // console.log('监听开始检测更新事件');
    // sendUpdateMessage({
    //   cmd: 'checking-for-update',
    //   message: message,
    // });
  });
  //监听发现可用更新事件
  autoUpdater.on('update-available', function(message) {
    console.log('监听发现可用更新事件');
    sendUpdateMessage({
      cmd: 'update-available',
      message: message,
    });
  });
  //监听没有可用更新事件
  autoUpdater.on('update-not-available', function(message) {
    console.log('监听没有可用更新事件');
    sendUpdateMessage({
      cmd: 'update-not-available',
      message: message,
    });
  });
  // 更新下载进度事件
  autoUpdater.on('download-progress', function(progressObj) {
    console.log('更新下载进度事件');
    sendUpdateMessage({
      cmd: 'download-progress',
      message: progressObj,
    });
  });
  //监听下载完成事件
  autoUpdater.on('update-downloaded', function(
    event,
    releaseNotes,
    releaseName,
    releaseDate,
    updateUrl
  ) {
    sendUpdateMessage({
      cmd: 'update-downloaded',
      message: {
        releaseNotes,
        releaseName,
        releaseDate,
        updateUrl,
      },
    });
    //退出并安装更新包,如果有下面这段代码,安装包下载完成之后会立刻退出软件并且安装
    // autoUpdater.quitAndInstall();
  });
  //接收渲染进程消息,开始检查更新
  ipcMain.on('checkForUpdate', (e, arg) => {
    console.log('接收渲染进程消息,开始检查更新');
    //执行自动更新检查
    // sendUpdateMessage({cmd:'checkForUpdate',message:arg})
    autoUpdater.checkForUpdates();
  });
  //接收渲染进程信息,是否立即更新
  ipcMain.on('quitAndInstall', (e, arg) => {
    console.log('接收渲染进程信息,是否立即更新');
    //退出并安装更新包
    autoUpdater.quitAndInstall();
  });
  // 手动下载更新文件
  ipcMain.on('confirmDownloadUpdate', () => {
    autoUpdater.downloadUpdate();
  });
}

页面进度条和相关提示的显示

新建一个softwareUpdate.vue

softwareUpdate.vue

<template>
  <el-dialog
    :title="percentage == 100 ? '下载完成' : '正在下载新版本,请稍候...'"
    :visible.sync="dialogVisible"
    width="500px"
    :close-on-click-modal="closeOnClickModal"
    :close-on-press-escape="closeOnPressEscape"
    :show-close="showClose"
    center
  >
    <div
      style="width: 100%; height: 50px; line-height: 50px; text-align: center"
    >
      <el-progress
        status="success"
        :text-inside="true"
        :stroke-width="20"
        :percentage="percentage"
        :width="strokeWidth"
        :show-text="true"
      ></el-progress>
    </div>
  </el-dialog>
</template>
<script>
let { ipcRenderer } = require("electron");
import config from '../../package.json'
export default {
  data() {
    return {
      dialogVisible: false,//是否打开弹窗
      closeOnClickModal: false,//是否可通过点击遮罩关闭 MessageBox
      closeOnPressEscape: false,//是否可通过按下 ESC 键关闭 MessageBox
      showClose: false,//是否显示关闭按钮
      percentage: 0,//进度条进度
      strokeWidth: 200,//进度条的厚度
      confirmShowClose: true,//是否显示右上角关闭按钮
      confirmShowCancelButton: true,//是否显示取消按钮
      forcedUpdating: false,//是否需要强制更新
      timeOut: null
    }
  },
  mounted() {
    //接收主进程版本更新消息
    ipcRenderer.on("message", (event, arg) => {
      if ("update-available" == arg.cmd) {
        //监听发现可用更新事件
        this.updateAvailable(arg)
      } else if ("download-progress" == arg.cmd) {
        // 更新下载进度事件
        this.downloadProgress(arg)
      } else if ("error" == arg.cmd) {
        //监听升级失败事件
        this.error(arg)
      } else if ('update-downloaded' == arg.cmd) {
        //监听下载完成事件
        this.updateDownloaded(arg)
      }
    });
    //2秒后开始检测新版本
    this.timeOut = window.setTimeout(() => {
      ipcRenderer.send("checkForUpdate");
    }, 2000);
  },
  methods: {
    //监听发现可用更新事件
    updateAvailable(arg) {
      let text
      //根据版本号来判断是否需要强制更新
      if (arg.message) {
        let A = config.version.split('.')[0]; // 本地版本号
        let a = arg.message.version.split('.')[0]; // 服务器安装包版本号
        let B = config.version.split('.')[1];
        let b = arg.message.version.split('.')[1];
        //如果版本号的第一位或者第二位是和目前的版本号不一样就需要强制更新
        if (a > A || b > B) {
          text = '发现新版本,需要立即更新才能使用!'
          this.confirmShowClose = false //是否显示右上角关闭按钮
          this.confirmShowCancelButton = false //是否显示取消按钮
          this.forcedUpdating = true //强制更新
        } else {
          text = '发现新版本,是否下载新版本?'
          this.forcedUpdating = false //寻求用户是否需要更新
        }
      }
      //显示升级对话框
      this.$confirm(text, '提示', {
        showClose: this.confirmShowClose,//是否显示右上角关闭按钮
        showCancelButton: this.confirmShowCancelButton,//是否显示取消按钮
        closeOnClickModal: false,//是否可通过点击遮罩关闭 MessageBox
        closeOnPressEscape: false,//是否可通过按下 ESC 键关闭 MessageBox
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.dialogVisible = true; //打开安装白下载进度弹窗
        ipcRenderer.send("confirmDownloadUpdate");   // 手动下载更新文件
      }).catch(() => {
      });
    },
    // 更新下载进度事件
    downloadProgress(arg) {
      //更新升级进度
      let percent = Math.round(parseFloat(arg.message.percent));
      this.percentage = percent;
    },
    //监听升级失败事件
    error(arg) {
      this.dialogVisible = false; //关闭弹窗
      // console.log('更新失败');
    },
    //监听下载完成事件
    updateDownloaded(arg) {
      //有时候网速太快会跳过获取进度,这里进度加个判断,手动设置获取更新进度
      this.percentage = this.percentage != 100 ? 100 : this.percentage
      //如果需要强制更新的就不需要再询问客户是否安装
      // console.log(this.forcedUpdating);
      if (this.forcedUpdating) {
        ipcRenderer.send("quitAndInstall"); //退出并安装更新包
      } else {
        this.$confirm('下载完成,是否立即更新?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          ipcRenderer.send("quitAndInstall"); //退出并安装更新包
        }).catch(() => {
          this.dialogVisible = false; //关闭弹窗
          this.$message({
            type: 'info',
            message: '已取消更新'
          });
        });
      }
    }
  },
  destroyed() {
    //清除定时器
    window.clearTimeout(this.timeOut);
  }
}
</script>

在APP.vue中引入这个组件即可。

下载进度的显示不一定使用element的el-dialog,也可以自定义根据需求生成动画。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值