我本人特別不喜歡那麼長篇博客,我儘量縮減。
參考1: https://blog.csdn.net/gsj4719896/article/details/100131840
參考2:https://www.jianshu.com/p/15bde714e198
第一步:安裝electron-updater
npm install electron-updater --save
第二步:在vue.config.js裏添加public配置,打包將會在dist目錄中生成latest.yml文件
- 我看很多文章都將public配置放在package.json的文件裏,我是放在vue.config.js文件了,請具體根據項目自行配置。
- url就是你打包上傳的地址的前綴,比如你打包後的文件會放在http://www.xxx.com/static/demo.exe,那麼這個url就是http://www.xxx.com/static/
- 關於latest.yml這個文件要放到和上傳文件一致的位置,要和2的位置保持一致http://www.xxx.com/static/latest.yml
第三步:請求服務器更新,將這部分的邏輯抽成一個update.js文件
import {
autoUpdater
} from 'electron-updater'
import {
ipcMain
} from 'electron'
let mainWindow = null;
export function updateHandle(window, feedUrl) {
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
}
})
//退出並安裝更新包
autoUpdater.quitAndInstall();
});
//接收渲染進程消息,開始檢查更新
ipcMain.on("checkForUpdate", (e, arg) => {
//執行自動更新檢查
// sendUpdateMessage({cmd:'checkForUpdate',message:arg})
autoUpdater.checkForUpdates();
})
}
//給渲染進程發送消息
function sendUpdateMessage(text) {
mainWindow.webContents.send('message', text)
}
第四步:background.ts引入update.js
1、我看好多文章都是在main/index.js引入的update.js,根據項目的具體結構來,反正都是要引進來的。
2、主要的代碼就兩行
import {updateHandle} from '@/utils/updater.js';
// --------放在createWindow方法最後一行就行-------------
updateHandle(win, 'http://static.xuezhong100.cn/client-software/');
import {updateHandle} from '@/utils/updater.js';
function createWindow() {
// Create the browser window.
win = new BrowserWindow({
width: 800,
height: 600,
frame: false,
center: true,
webPreferences: {
nodeIntegration: true,
webSecurity: false
// preload: path.join(__dirname, './preload')
}
})
var url;
if (process.env.WEBPACK_DEV_SERVER_URL) {
url = process.env.WEBPACK_DEV_SERVER_URL as string;
if (!process.env.IS_TEST) win.webContents.openDevTools()
} else {
createProtocol('app')
url = 'app://./index.html';
}
win.webContents.openDevTools()
win.loadURL(url)
win.on('closed', () => {
mainWindow = null
})
// 更新,第二個參數就是public裏的url,我這裏寫死了,你直接去找
updateHandle(win, 'http://static.xuezhong100.cn/client-software/');
}
第五步:App.vue處理邏輯
<template>
<div id="app">
<router-view></router-view>
<el-dialog
title="正在更新新版本,請稍候..."
:visible.sync="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>
let ipcRenderer = require("electron").ipcRenderer;
export default {
name: "app",
data() {
return {
dialogVisible: false,
closeOnClickModal: false,
closeOnPressEscape: false,
showClose: false,
percentage: 0,
strokeWidth:200
};
},
mounted() {
let _this = this;
//接收主進程版本更新消息
ipcRenderer.on("message", (event, arg) => {
// for (var i = 0; i < arg.length; i++) {
console.log(arg);
if ("update-available" == arg.cmd) {
//顯示升級對話框
_this.dialogVisible = true;
} else if ("download-progress" == arg.cmd) {
//更新升級進度
/**
*
* message{bytesPerSecond: 47673
delta: 48960
percent: 0.11438799862426002
total: 42801693
transferred: 48960
}
*/
console.log(arg.message.percent);
let percent = Math.round(parseFloat(arg.message.percent));
_this.percentage = percent;
} else if ("error" == arg.cmd) {
_this.dialogVisible = false;
_this.$message("更新失敗");
}
// }
});
ipcRenderer.send("checkForUpdate");
}
};
</script>
第六步:結果+錯誤分析
然後讓我們打包一份,打包的版本是比如是1.1.0,將latest.yml(裏面對應exe的版本信息、稱之類的)和對應的exe放到服務器地址上,將本地的package.json的version改成1.0.0(因爲更新是通過版本號的對比控制的)更新操作就會觸發,這時候如果你能順利顯示下圖,說明你這邊已經很順利的完成了
很不幸,如果你報錯了
- 問題描述:問題4:控制檯會出現:electron-updater code: “ENOENT” errno: -4058 path:
“E:\project1\edu-student\dist_electron\dev-app-update.yml” syscall:
“open” - 問題描述:dev-app-update.yml文件不存在
- 問題分析:dev-app-update.yml文件沒有打包到default_app.asar中,dev-app-update.yml的格式是怎樣的,查看打包後的文件dist\win-unpacked\resources,發現其中一個app-update.yml文件,查閱資料後發現其實dev-app-update.yml的文件內容格式是一樣的
- 問題解決:electron-updater中提供了這個文件的屬性配置updateConfigPath,修改updater.js文件,我們將調用的地址修改一下。
autoUpdater.updateConfigPath = path.join(__filename, '../../dist/win-ia32-unpacked/resources/app-update.yml')
改到這一步,你還報錯,比如說命令行報錯,下載失敗balabla的,看下你請求的exe地址是不是有中文,中文會到導致下載失敗,請改成英文。對應的yml裏的文件名稱也改成英文,在試一下。我就是走到這一步才成功才下載成功!!!!走了很多彎路,各種試,到最後下載下來,成就感還是蠻強的。