首页 > 技术文章 > electron-updater实现更新electron应用程序

jtjianfeng 2020-10-19 17:18 原文

electron-updater实现更新electron应用程序

第一步

  1. 安装"electron-updater": "^4.3.5",
  2. 打开package.json文件在build对象下添加publish配置,
  "build": {
  "productName": "xxx",
  "appId": "org.simulatedgreg.electron-vue",
  "directories": {
    "output": "build"
  },
  ---------------------------------------------
  "publish": [
    {
      "provider": "generic",
      "url": "https://xxx.com"
     //注:这个url就是放.yml文件和安装包的服务器地址,我这里用的是阿里云oss地址
    }
  ],
  --------------------------------------------------
  "files": [
    "dist/electron/**/*"
  ]

第二步

  1. 在main文件夹下面创建更新文件update.js
import { autoUpdater } from 'electron-updater'
import { ipcMain } from 'electron'

let mainWindow = null;
export function updateHandle(window, feedUrl) {
  mainWindow = window;
  let message = {
      error: '检查更新出错',
      checking: '正在检查更新',
      updateAva: '检测到新版本,正在下载',
      updateNotAva: '您已经更新到最新版本了',
  };
  //设置更新包的地址
  autoUpdater.setFeedURL(feedUrl);
  //监听升级失败事件
  autoUpdater.on('error', function (error) {
      sendUpdateMessage({
          cmd: 'error',
          message: error
      })
  });
  //监听开始检测更新事件
  autoUpdater.on('checking-for-update', function (message) {
      sendUpdateMessage({
          cmd: 'checking-for-update',
          message: message
      })
  });
  //监听发现可用更新事件
  autoUpdater.on('update-available', function (message) {
      sendUpdateMessage({
          cmd: 'update-available',
          message: message
      })
  });
  //监听没有可用更新事件
  autoUpdater.on('update-not-available', function (message) {
      sendUpdateMessage({
          cmd: 'update-not-available',
          message: message
      })
  });

  // 更新下载进度事件
  autoUpdater.on('download-progress', function (progressObj) {
      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) => {
      //执行自动更新检查
      // sendUpdateMessage({cmd:'checkForUpdate',message:arg})
      autoUpdater.checkForUpdates();
  })
}
//给渲染进程发送消息
function sendUpdateMessage(text) {
  mainWindow.webContents.send('message', text)
}
  1. 在main文件夹下面的index.js中引入update.js
import { updateHandle } from './update'

mainWindow.on('closed', () => {
    mainWindow = null
  })
----------------------------------------------------
  let feedUrl = "https://xxxxx.com";
  updateHandle(mainWindow,feedUrl);
-----------------------------------------------------
}

第三步

  1. APP.js文件中检测更新
  <template>
  <div id="app">
    <router-view></router-view>
    <el-dialog
      title="正在更新新版本,请稍候..."
      :visible.sync="dialogVisible"
      width="60%"
      :close-on-click-modal="closeOnClickModal"
      :close-on-press-escape="closeOnPressEscape"
      :show-close="showClose"
      center
    >
      <div style="width:100%;height:15vh;line-height:15vh;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>
  </div>
</template>

<script>
let ipcRenderer = require("electron").ipcRenderer;
let _this = this;
//接收主进程版本更新消息
ipcRenderer.on("message", (event, arg) => {
  // for (var i = 0; i < arg.length; i++) {
  console.log(arg);
  if ("update-available" == arg.cmd) {
    //显示升级对话框
    _this.dialogVisible = true;
  } else if ("download-progress" == arg.cmd) {
    //更新升级进度
    /**
     * 
     * message{bytesPerSecond: 47673
      delta: 48960
      percent: 0.11438799862426002
      total: 42801693
      transferred: 48960
      }
     */
    console.log(arg.message.percent);
    let percent = Math.round(parseFloat(arg.message.percent));
    _this.percentage = percent;
  } else if ("error" == arg.cmd) {
    _this.dialogVisible = false;
    _this.$message("更新失败");
  }
  // }
});
 ipcRenderer.send("checkForUpdate");
//20秒后开始检测新版本
// let timeOut = window.setTimeout(() => {
//   ipcRenderer.send("checkForUpdate");
// }, 20000);
clearTimeout;
//间隔1小时检测一次
// let interval = window.setInterval(() => {
//   ipcRenderer.send("checkForUpdate");
// }, 3600000);

export default {
  name: 'App',
  data() {
    return {
      dialogVisible: false,
      closeOnClickModal: false,
      closeOnPressEscape: false,
      showClose: false,
      percentage: 0,
      strokeWidth:200
    };
  },
  mounted() {
    _this = this;
  },
  destroyed() {
    window.clearInterval(interval);
    window.clearInterval(timeOut);
  }

}
</script>

第四步

将项目打包yarn build,将打包后生成的build目录下的latest.yml和安装包.exe文件传入服务器即可

坑!!!

注:我在开发的时候遇到了一个坑,打包成功后打开项目报错 A JavaScript error occurrend in the main process

这是electron版本过低导致的,后来我将版本升级到4.0.1,再打包就正常运行了。

本文使用 mdnice 排版

推荐阅读