第一步 安装electron-updater
npm install electron-updater --save
第二步 打开package.json文件在build标签下添加public配置,执行npm run build时,将会在build目录中生成latest.yml文件 nsis
"nsis": {
"oneClick": false,
"allowToChangeInstallationDirectory": true,//自定义安装目录
"allowElevation": true,
"installerIcon": "build/icons/icon.ico",
"createDesktopShortcut": true //生成桌面图标
},
"publish": [{
"provider": "generic",
"url": "http://192.168.10.47:8000"
}],
第三步 新建Update.js 升级文件
renderer/utils/Update.js
import {
autoUpdater
} from 'electron-updater'
import {
ipcMain
} from 'electron'
let mainWindow = null;
const path = require('path') // 引入path模块
const fs = require('fs-extra')
import packageJson from "../../../package.json"
export function updateHandle(window, feedUrl) {
delFile()
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
}
})
delFile()
//退出并安装更新包
autoUpdater.quitAndInstall();
});
//接收渲染进程消息,开始检查更新
ipcMain.on("checkForUpdate", (e, arg) => {
//执行自动更新检查
// sendUpdateMessage({cmd:'checkForUpdate',message:arg})
autoUpdater.checkForUpdates();
})
}
//给渲染进程发送消息
function sendUpdateMessage(text) {
mainWindow.webContents.send('message', text)
}
// 删除文件夹
function delFile() {
// 更新前,删除本地安装包 ↓
let updaterCacheDirName = packageJson.name + '-updater'
const updatePendingPath = path.join(autoUpdater.app.baseCachePath, updaterCacheDirName, 'pending')
// 首先判断是否存在这个文件夹
fs.exists(updatePendingPath, function(exists) {
// 存在
if (exists == true) {
// 先清空文件夹里面的东西
fs.emptyDir(updatePendingPath)
// 再删除文件夹
fs.rmdirSync(updatePendingPath)
// 更新前,删除本地安装包 ↑
}
});
}
第四步 在main/index.js主进程中进行导入:
import {
app,
BrowserWindow
} from 'electron'
//引入update.js
import {updateHandle} from '../renderer/utils/Update.js';
const path = require('path')
/**
* Set `__static` path to static files in production
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
*/
if (process.env.NODE_ENV !== 'development') {
global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
}
let mainWindow
const winURL = process.env.NODE_ENV === 'development' ?
`http://localhost:9080` :
`file://${__dirname}/index.html`
console.log("__dirname==" + __dirname);
function createWindow() {
console.log('createWindow');
/**
* Initial window options
*/
mainWindow = new BrowserWindow({
height: 540,
useContentSize: true,
width: 1080,
center: true, // 窗口居中
// resizable: false, // 窗口大小是否可改变
maximizable: true, // 窗口是否可以最大化
// icon: path.join(__static, '/favicon.ico'), // 更换图标, 这里的图标仅支持svg 和icon 图标
// frame: false,
// 加入这个参数即可
webPreferences: {
webSecurity: false,
nodeIntegrationInWorker: true
}
})
mainWindow.loadURL(winURL)
//开启调试
mainWindow.webContents.openDevTools();
mainWindow.setMenuBarVisibility(false);
mainWindow.on('closed', () => {
mainWindow = null
});
//设置版本更新地址,即将打包后的latest.yml文件和exe文件同时放在
//http://xxxx/test/version/对应的服务器目录下,该地址和package.json的publish中的url保持一致
let feedUrl = "http://xxxx/test/version/";
//检测版本更新
updateHandle(mainWindow,feedUrl);
}
app.on('ready', createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') { //mac
app.quit()
}
})
app.on('activate', () => {
if (mainWindow === null) {
createWindow()
}
});
第五步 渲染进程显示更新进度 在App.vue中处理
<template>
<v-main>
<v-btn elevation="2" @click="btnClick()">升级</v-btn>
测试版333333333333
</v-main>
</template>
<script>
let ipcRenderer = require("electron").ipcRenderer;
export default {
methods: {
btnClick() {
ipcRenderer.send("checkForUpdate");
},
},
mounted() {
//接收主进程版本更新消息
ipcRenderer.on("message", (event, arg) => {
if (arg.cmd == 'error') {
console.log('------------监听升级失败事件--------' + JSON.stringify(arg.message))
} else if (arg.cmd == 'checking-for-update') {
console.log('------------监听开始检测更新事件--------' + JSON.stringify(arg.message))
} else if (arg.cmd == 'update-available') {
console.log('------------监听发现可用更新事件--------' + JSON.stringify(arg.message))
} else if (arg.cmd == 'update-not-available') {
console.log('------------监听没有可用更新事件--------' + JSON.stringify(arg.message))
} else if (arg.cmd == 'download-progress') {
console.log('------------更新下载进度事件--------' + JSON.stringify(arg.message))
} else if (arg.cmd == 'update-downloaded') {
console.log('------------监听下载完成事件--------' + JSON.stringify(arg.message))
}
});
}
}
</script>
<style scoped>
</style>
网友评论