Electron + vue 实现更新

432 阅读1分钟

项目上刚好有需求,研究挺多文档,最后终于找到能成功的。

blog.csdn.net/qq_41614928…

juejin.cn/post/691873…

最开始搭建更新服务器,折腾半天,最后发现没必要,直接用静态资源服务器就完事。

安装electron-updater,然后配置好nsis,publish

"build": {
    "appId": "your_electron_name",
    "icon": "public/icon/my.ico",
    "directories": {
      "output": "build"
    },
    "publish": [
      {
        "provider": "generic",
        "url": "http://XXXXX.test/update/"
      }
    ],
    "win": {
      "icon": "public/icon/my.ico",
      "artifactName": "${productName}_setup_${version}.${ext}",
      "target": [
        "nsis"
      ]
    },
    "mac": {
      "icon": "public/icon/my.ico",
    },
    "files": [
      "./main.js",
      "./package.json",
      "./dist/**"
    ],
    "nsis": {
      "oneClick": false,
      "allowElevation": true,
      "allowToChangeInstallationDirectory": true,
      "createDesktopShortcut": true,
      "createStartMenuShortcut": true,
      "perMachine": false,
      "unicode": true,
      "deleteAppDataOnUninstall": false,
      "shortcutName": "更新测试"
    },
    "extends": null
  }

在vue中引入时候要加window,还有如果需要进度条那需要引入element

<template>
  <div class="">
    <div class="main">
      <h2>这里是首页 </h2>
    </div>
      
      <el-dialog
      title="正在更新新版本,请稍候..."
      v-model="dialogVisible" 
      width="60%"
      :close-on-click-modal="closeOnClickModal"
      :close-on-press-escape="closeOnPressEscape"
      :show-close="showClose"
      center
    >
      <div
        style="width: 100%; height: 20vh; line-height: 20vh; 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>
import { getCurrentInstance } from "vue";
// 引入element
import { ElMessageBox, ElMessage, dialog } from "element-plus";
const { ipcRenderer } = window.require("electron");
export default {
  components: {},
  data() {
    return {
       dialogVisible: false, // 更新窗口展示
      closeOnClickModal: false,
      closeOnPressEscape: false,
      showClose: false,
      percentage: 0,
      strokeWidth: 200,
      };
  },
  setup() {
    const { proxy } = getCurrentInstance();

    return { proxy };
  },
  created() {},
  mounted() {
    console.log("this home");

  //新版本检测
    console.log("开始新版本检测");
    // ipcRenderer.send("checkForUpdate");
    ipcRenderer.send("app_version");

    //获取当前版本
    ipcRenderer.on("app_version", (event, arg) => {
      console.log("获取当前版本");
      ipcRenderer.removeAllListeners("app_version");
      console.log(arg);
      // console.log(event);
    });

    //下载中触发
    ipcRenderer.on("downloadProgress", (event, progressObj) => {
      // console.log(event);
      console.log(progressObj);
      let downloadPercent = progressObj.percent || 0;
      console.log("正在下载..." + "downloadPercent");
      let percent = Math.round(parseFloat(progressObj.percent));
      this.percentage = percent;
    });

    //检查是否有新版本
    ipcRenderer.on("checking_for", (event, arg) => {
      console.log("检查是否有新版本");
      // console.log(event);
      console.log(arg);
    });

    //发现新版本
    ipcRenderer.on("update_available", (event, arg) => {
      console.log("新版本信息...");
      this.dialogVisible = true;
      console.log(event);
      console.log(arg);
    });

    // 更新出错
    ipcRenderer.on("update_error", (event, arg) => {
      console.log("更新出错...");
      this.dialogVisible = false;
      console.log(event);
      console.log(arg);
    });

    //下载成功触发
    ipcRenderer.on("update_downloaded", () => {
      ipcRenderer.removeAllListeners("update_downloaded");
      console.log("下载成功!触发更新");

      ElMessageBox.alert("请重新打开软件以完成更新", "更新完成", {
        confirmButtonText: "OK",
        callback: (action) => {
          // 此处强制更新
          ipcRenderer.send("isUpdateNow");
        },
      });
    });
    
  },
  props: {},
  methods: {},
};
</script>
<style lang="scss" scoped>
.main {
  width: 100%;
  text-align: center;
  display: block;
  padding: 30px 0;
}
</style>

main.js里创建好窗口调用更新

  // 检测更新
  updateHandle();
let uploadUrl = "XXX.com/upload/"
//检测更新
function updateHandle() {
 console.log("检测更新中。。。" + uploadUrl);
 let message = {
   error: '检查更新出错',
   checking: '正在检查更新……',
   updateAva: '检测到新版本,正在下载……',
   updateNotAva: '现在使用的就是最新版本,不用更新',
 };
 const os = require('os');

 autoUpdater.setFeedURL(uploadUrl);
 console.log("0000000000000")
 // setTimeout(()=>{
 //   console.log("延迟触发更新")
 // autoUpdater.checkForUpdates();
 // },3000)

 autoUpdater.on('error', function (error) {
   console.log(message.error)
   //sendUpdateMessage(message.error)
 });
 autoUpdater.on('checking-for-update', function () {
   mainWindow.webContents.send('checking_for', "正在检测更新...")
   console.log("正在检测更新...")
   //sendUpdateMessage(message.checking)
 });

 //当发现一个可用更新的时候触发,更新包下载会自动开始
 autoUpdater.on('update-available', function (info) {
   mainWindow.webContents.send('update_available')
   autoUpdater.downloadUpdate().then((path) => {
     console.log('download path', path)
   }).catch((e) => {
     console.log(e)
   })

 });

 //当没有可用更新的时候触发
 autoUpdater.on('update-not-available', function (info) {
   console.log("当前没有可用更新")
   // sendUpdateMessage(message.updateNotAva)
 });

 // 更新下载进度事件
 autoUpdater.on('download-progress', function (progressObj) {
   console.log(progressObj)
   mainWindow.webContents.send('downloadProgress', progressObj)
 })
 //安装包下载完成
 autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
   console.log("666666666666")
   mainWindow.webContents.send('update_downloaded')
   ipcMain.on('isUpdateNow', (e, arg) => {
     console.log(arguments);
     console.log("开始更新");
     // 退出并安装
     autoUpdater.quitAndInstall();
   });
 });
 //html页面加载后触发此更新
 ipcMain.on("checkForUpdate", () => {
   console.log('页面加载完成!!!!')
   //执行自动更新检查
   autoUpdater.checkForUpdates();
 })
 //获取当前版本
 ipcMain.on('app_version', (event) => {
   event.sender.send('app_version', { version: app.getVersion() });
 });

}

然后资源服务器放打包好的latest.yml 和 setup.exe文件就行