vue2.0+electron+electron-builder+electron-updater实现打包成exe桌面应用并自动更新
vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
项目地址:https://gitcode.com/gh_mirrors/vu/vue
免费下载资源
·
1.版本
Node (20.12.2)
Npm (10.5.2)
Vue (2.6.4)
Eelectron第三方库 (31.2.1)
electron-builder 打包工具 (13.6.9)
electron-updater 自动更新依赖 (6.2.1)
2.打包成exe文件实现步骤
2.1 安装electron
npm i electron
2.2 添加打包工具
vue add electron-builder
安装后src下会自动生成background.js文件
package.json生成对应的命令
并把background.js作为入口文件
package.json修改如下内容(解决打包不成功的问题)
将
"electron:build": "vue-cli-service electron:build",
改成
"electron:build": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service electron:build",
2.3 命令
运行命令:npm run electron:serve
打包命令:npm run electron:build
2.4 解决打包时的报错问题
1.下载与当前版本一致的electron-v13.6.9-win32-x64,放在C:\Users\DELL\AppData\Local\electron\Cache 下
2.下载对应的winCodeSign 解压后放在
C:\Users\DELL\AppData\Local\electron-builder\Cache\winCodeSign 下
3.下载对应nsis 解压后放在
C:\Users\DELL\AppData\Local\electron-builder\Cache\nsis 下
注:可以复制错误提示里面的链接下载相关文件
2.5 打包后生成的文件
双击exe文件安装成桌面端应用
3.自动更新实现步骤
3.1配置生成latest.yml文件
注:只有配置了以下内容,在打包的时候才会产生latest.yml这个文件,这个文件就是对安装包版本的一个描述,在进行版本比对的时候 就是在读取这个文件的内容,才能够实现自动更新
在vue.config.js文件
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
lintOnSave: false,
pluginOptions: {
electronBuilder: {
customFileProtocol: "./", //解决打包之后elementui不显示icon图标
nodeIntegration: true,
builderOptions: {
nsis: {
allowToChangeInstallationDirectory: true, //自定义安装路径
oneClick: false,
allowElevation: false,//安装时不请求管理员
perMachine: true, // 避免安装时的用户选择
createDesktopShortcut: true, // 创建桌面快捷方式
runAfterFinish: true, // 安装完成后运行
},
win: {
publish: [{
provider: "generic",
url: "http://192.168.3.43/dist/", //更新包服务器上地址
}],
},
productName: '智能刀具监测系统' //项目名
}
},
},
})
将latest.yml文件和生成的.exe文件放在服务器上,会自动检测版本
3.2 安装自动更新依赖electron-updater
npm i electron-updater
3.3 自动更新代码
3.3.1 在background.js同级目录下创建handleUpdate.js文件
import {
autoUpdater
} from 'electron-updater'
import {
ipcMain, dialog
} from 'electron'
let mainWindow = null;
export function handleUpdate(window, feedUrl) {
mainWindow = window;
let message = {
error: '检查更新出错',
checking: '正在检查更新……',
updateAva: '检测到新版本,正在下载……',
updateNotAva: '现在使用的就是最新版本,不用更新',
};
`autoUpdater.autoDownload = false;` //取消自动下载
//设置更新包的地址
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("quit-install", (e, arg) => {
autoUpdater.quitAndInstall();
})
//接收渲染进程消息,开始检查更新
ipcMain.on("checkForUpdate", (e, arg) => {
autoUpdater.checkForUpdates();
})
}
//给渲染进程发送消息
function sendUpdateMessage(text) {
mainWindow.webContents.send('message', text)
}
3.3.2 在background.js引入handleUpdate.js文件
const { handleUpdate } = require('./handleUpdate') //根据自己路径引入
//检查更新 http://192.168.3.43/dist/ 新版本更新包访问路径
handleUpdate(win, "http://192.168.3.43/dist/")
3.3.3 background.js完整代码
'use strict'
import { app, protocol, BrowserWindow } from 'electron'
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
const {
handleUpdate
} = require('./handleUpdate') //根据自己路径引入
const isDevelopment = process.env.NODE_ENV !== 'production'
const path = require('path')
// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([
{ scheme: 'app', privileges: { secure: true, standard: true } }
])
async function createWindow() {
// Create the browser window.
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION
}
})
win.maximize();//默认打开窗口最大化
win.show();
if (process.env.WEBPACK_DEV_SERVER_URL) {
// Load the url of the dev server if in development mode
await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
if (!process.env.IS_TEST) win.webContents.openDevTools()
} else {
createProtocol('app')
// Load the index.html when not in development
win.loadURL('app://./index.html')
}
//检查更新 http://192.168.3.43/dist/ 新版本更新包访问路径
handleUpdate(win, "http://192.168.3.43/dist/")
}
// Quit when all windows are closed.
app.on('window-all-closed', () => {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('quit', () => {
app.quit()
})
app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', async () => {
if (isDevelopment && !process.env.IS_TEST) {
// Install Vue Devtools
try {
await installExtension(VUEJS_DEVTOOLS)
} catch (e) {
console.error('Vue Devtools failed to install:', e.toString())
}
}
createWindow()
})
// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {
if (process.platform === 'win32') {
process.on('message', (data) => {
if (data === 'graceful-exit') {
app.quit()
}
})
} else {
process.on('SIGTERM', () => {
app.quit()
})
}
}
3.3.4在App.vue执行自动更新
每隔10分钟对比服务器上的版本,版本不同执行自动更新
<script>
let ipcRenderer = require("electron").ipcRenderer;
export default {
components: {
},
data() {
return {
};
},
created() {},
unmounted() {
clearInterval(this.timer);
},
mounted() {
console.log(ipcRenderer);
let _this = this;
//新增
this.timer = setInterval(() => {
setTimeout(() => {
console.log('执行定时器');
ipcRenderer.send("checkForUpdate");
}, 1);
}, 600000);
//接收主进程版本更新消息
ipcRenderer.on("message", (event, arg) => {
console.log(arg);
});
},
};
</script>
3.4 实现强制安装并运行程序
在handleUpdate.js文件夹中的监听下载完成事件中配置 autoUpdater.quitAndInstall();
// 监听下载完成事件
autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl) {
sendUpdateMessage({
cmd: 'update-downloaded',
message: {
releaseNotes,
releaseName,
releaseDate,
updateUrl
}
})
//退出并安装更新包
autoUpdater.quitAndInstall();
});
在package.json配置
"scripts": {
"start": "electron .",
}
编写installer.nsh脚本,实现安装成功之后自动运行程序
将installer.nsh脚本放在vue项目根路径下的build文件,没有的话自己创建
!macro customFinishPage
AutoCloseWindow true
Function StartApp
${if} ${isUpdated}
StrCpy $1 "--updated"
${else}
StrCpy $1 ""
${endif}
${StdUtils.ExecShellAsUser} $0 "$launchLink" "open" "$1"
FunctionEnd
Function .onInstSuccess
Call StartApp
FunctionEnd
!macroend
GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5
* chore: fix link broken
Signed-off-by: snoppy <michaleli@foxmail.com>
* Update packages/template-compiler/README.md [skip ci]
---------
Signed-off-by: snoppy <michaleli@foxmail.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891
Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
更多推荐
已为社区贡献4条内容
所有评论(0)