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搭建的本地服务器为例
放入即可
因为我本地服务器忘了启动,所以弹出错误
正常更新情况
下载完成就会自动退出程序,启动安装程序!