electron-vue应用程序更新功能实现


文章目录

  • electron-vue应用程序更新功能实现
  • 前言
  • 一、使用步骤
  • 1.引入安装electron-updater
  • 2.package.json文件build属性下添加publish属性
  • 3.主进程文件夹main目录下创建update.js 存放更新相关事件
  • 4.update.js同级目录下也创建app-update.yml文件
  • 5.主进程index.js中引入使用步骤3创建的update.js 中的updateHandle()方法
  • 6.components中创建update.vue组件,页面中引用该组件
  • 7.打包新版本放到服务器,打包前修改版本号,新版本版本号高于当前版本才会触发更新
  • 8.将打包代码放到服务器目录中,这里以phpstudy搭建的本地服务器为例



前言

工作中重构一个electron的小项目,由于项目是特殊的应用场景,所以之前每次项目打包之后都需要通过U盘拷贝传递安装,这样就导致安装体验极差,所以就使用electron-updater在应用内增加自动检查更新以及点击检查更新下载安装包功能
electron版本:2.0.4
electron-updater版本:4.0.0


一、使用步骤

1.引入安装electron-updater

代码如下(示例):

npm install electron-updater --save

2.package.json文件build属性下添加publish属性

代码如下(示例):

"publish": [
      {
        "provider": "generic", //  这个属性固定
        "url": "http://192.168.0.117/app" //  服务器的路径,存放你打包的新版本应用,用户端会请求这个地址查找新版本
      }
    ],

3.主进程文件夹main目录下创建update.js 存放更新相关事件

import {
    autoUpdater
} from 'electron-updater'
const path = require('path')
if (process.env.NODE_ENV === 'development') {
    autoUpdater.updateConfigPath = path.join(__dirname, 'app-update.yml')
} else {
    autoUpdater.updateConfigPath = path.join(__dirname, '../../../app-update.yml')
}
import {
    app,
    ipcMain
} from 'electron'
let webContents
export function updateHandle(window, feedUrl, c) {
    //  关闭检测到更新就自动下载,由用户手动确认下载
    autoUpdater.autoDownload = false
    webContents = c
    //设置更新包的地址
    autoUpdater.setFeedURL(feedUrl);
    //监听升级失败事件
    autoUpdater.on('error', function (error) {
        sendUpdateMessage({
            cmd: 'error',
            message: error
        })
    });
    //监听开始检测更新事件
    autoUpdater.on('checking-for-update', function (message) {
        console.log(111,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
            }
        })
        //退出并安装更新包,不退出如果取消安装的话,无法再次启动安装程序
        app.quit()
        autoUpdater.quitAndInstall();
        
    });

    //ipcMain进程通信接收渲染进程消息,开始检查更新
    ipcMain.on("checkForUpdate", (e, arg) => {
        autoUpdater.checkForUpdates();
    })
    // 退出并安装
    ipcMain.on('confirm-update', () => {
        app.quit()
        autoUpdater.quitAndInstall();
    })
     // 手动下载更新文件
     ipcMain.on('confirm-downloadUpdate', () => {
        autoUpdater.downloadUpdate()
    })

}
//ipcMain进程通信给渲染进程发送消息
function sendUpdateMessage(text) {
    webContents.send('message', text)
}

4.update.js同级目录下也创建app-update.yml文件

provider: generic
url: '"http://192.168.0.117/app/"' //  这个换成你自己的地址,同步骤2package.json中设置的url
updaterCacheDirName: productiontools-updater

5.主进程index.js中引入使用步骤3创建的update.js 中的updateHandle()方法

//引入update.js
import {updateHandle} from './update.js';
function createWindow() {
  mainWindow = new BrowserWindow({
    width: 1920,
    height: 1080,
    minWidth: 1280,
    minHeight: 638,
    icon: path.join(__dirname, '../renderer/assets/img/logo.png'),
    webPreferences: { webSecurity: false },

  })
  //  注册快捷方式 打开调试
  globalShortcut.register('f11', (event, arg) => {
    if (mainWindow != null) {
      mainWindow.openDevTools();
    }
  })
  mainWindow.loadURL(winURL)

  mainWindow.on('closed', () => {
    mainWindow = null;
  })
  //  此处调用,
  //设置版本更新地址,即将打包后的latest.yml文件和exe文件同时放在    
   //http://xxxx/test/version/对应的服务器目录下,该地址和package.json的publish中的url保持一致
  webContents = mainWindow.webContents;
  let feedUrl = "http://192.168.0.117/app/";
  //检测版本更新
  updateHandle(mainWindow,feedUrl,webContents);

}

6.components中创建update.vue组件,页面中引用该组件

<template>
  <div class="update">
  <!-- 下载中下载图标就为红色,根据下载进程传递的进度判断设置相应的class -->
    <i
      @click="getUpdate"
      class="iconfont icon-jianchagengxin"
      style="font-size: 24px"
      :class="{red:percent>0&&percent<99}"
    ></i>
    <!-- 提示框 -->
    <el-dialog
      :title="error ? '更新错误!' : '发现新版本'"
      :visible.sync="dialogVisible"
      width="30%"
      center
    >
      <div class="content">
        <div class="tip" v-if="!error">存在新版本可用,是否立即更新?</div>
        <div class="tip" v-else>
          <i class="iconfont icon-cuowu tip"></i> 更新错误
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">关 闭</el-button>
        <el-button :disabled="percent>0&&percent<99" v-if="!error" type="primary" @click="nowDownload"
          >立即下载</el-button
        >
      </span>
    </el-dialog>
    <!-- 下载框 -->
    <el-dialog
      :show-close="false"
      title="正在下载更新"
      :visible.sync="downDialog"
      width="30%"
      center
    >
      <div>
        <el-progress
          :text-inside="true"
          :stroke-width="26"
          :percentage="percent"
        ></el-progress>
      </div>
    </el-dialog>
  </div>
</template>
<script>
//  进程通信
const { ipcRenderer } = require("electron");
export default {
  data() {
    return {
      timeOut: null,  //  初始加载20秒后请求一次更新的计时器id
      interval: null, //  间隔1小时检测一次更新的计时器id
      dialogVisible: false,  //  更新进度弹窗
      downDialog: false, //  下载进度弹窗
      error: false, //  是否下载错误
      percent: 0, //  下载进度
      downOk: false, //  下载是否完成
    };
  },
  created() {},
  methods: {
    //  检查更新
    getUpdate() {
      //  当前下载中的话,就禁止进程通信再次检查更新
      if (this.percent>0) {
        this.downDialog=true
        return
      }
      ipcRenderer.send("checkForUpdate");
    },
    //  立即下载
    nowDownload() {
        //  发送下载请求
        ipcRenderer.send("confirm-downloadUpdate");
        //  弹出下载进度框
        this.downDialog = true;
    },
  },
  mounted() {
    //接收主进程版本更新消息
    ipcRenderer.on("message", (event, arg) => {
      this.error = false;
      this.downOk = false;
      console.log(arg);
      if ("update-available" == arg.cmd) {
        //发现更新  显示升级对话框
        this.dialogVisible = true;
      } else if ("download-progress" == arg.cmd) {
        // 下载中... 下载进度值更新
        this.percent= ~~arg.message.percent;
      } else if ("error" == arg.cmd) {
        //  更新错误...  
        //  1.弹出下载提示框
        this.dialogVisible = true;
        //  2.关闭下载进度框
        this.downDialog = false;
        //  3.下载进度归零
        this.percent =0
        //  4.下载提示框内容提示为更新错误
        this.error = true;
      } else if ("update-downloaded" == arg.cmd) {
        //  下载完成 退出主程序,启动安装程序
          this.percent =100
        this.downOk = true;
        ipcRenderer.send("confirm-update");
      }else if ("update-not-available" == arg.cmd) {
          this.$message.success("暂无更新,当前已是最新版!")
      }
      // }
    });
    //20秒后开始检测新版本
    this.timeOut = window.setTimeout(() => {
      ipcRenderer.send("checkForUpdate");
    }, 20000);
    //间隔1小时检测一次
    this.interval = window.setInterval(() => {
      ipcRenderer.send("checkForUpdate");
    }, 3600000);
  },
  beforeDestroy() {
    clearInterval(this.interval);
    clearInterval(this.timeOut);
    this.interval=null
    this.timeOut=null
  },
};
</script>
<style scoped>
.icon-jianchagengxin {
  cursor: pointer;
}
.tip {
  text-align: center;
  font-size: 24px;
}
.red {
  color: red;
}
</style>

7.打包新版本放到服务器,打包前修改版本号,新版本版本号高于当前版本才会触发更新

在package.json文件更改version字段

8.将打包代码放到服务器目录中,这里以phpstudy搭建的本地服务器为例

放入即可

electron axios 超时 electron检查更新_electron axios 超时


因为我本地服务器忘了启动,所以弹出错误

electron axios 超时 electron检查更新_服务器_02

正常更新情况

electron axios 超时 electron检查更新_服务器_03

electron axios 超时 electron检查更新_electron_04

下载完成就会自动退出程序,启动安装程序!