增量更新說明文件
提前準備
- 準備本地或者遠端伺服器或者遠端靜態檔案url
npm i -g http-server
cd yourFileFolder // 進入任意資料夾
http-server -p 4000 // 快速開啟本地服務,用於儲存更新檔案
- 配置和打包,拿到更新檔案內容並壓縮
// package.json
// 關閉asar模式
"asar": false,
// 打包
npm run pack-windows
// 進入打好的windows包
cd release\0.x.x_setup\win-unpacked\resources
// 壓縮app資料夾 => app.zip, 拷貝app-update.yml和app.zip
-
app.zip app-update.yml 傳到伺服器
-
本地流程,啟動客戶端,點選增量更新
// 入口
// src\render\components\AutoUpdate\index.tsx
<Button type='primary' onClick={() => checkForPartUpdates()} style={{ marginLeft: 10 }}>
增量更新
</Button>
// 本地檢查與伺服器的version版本比較
// 如果找到新版本,則向主程式通訊,通知checkForPartUpdates開始更新
// src\render\utils\autoUpdate\partUpdate.js
/** 檢查更新 */
export async function checkForPartUpdates() {
try {
// check version 檢查版本
const res = await checkVersion()
if (res && res === 'OPEN_PART_UPDATE') {
// 增量更新
console.log('OPEN_PART_UPDATE')
confirm({
title: '檢測到更新',
icon: <ExclamationCircleOutlined />,
content: (
<div>
<p>是否更新?</p>
</div>
),
okText: '確認',
cancelText: '取消',
onOk() {
ipc && ipc.send('checkForPartUpdates')
message.info('請耐心等待幾秒..')
},
onCancel() {
console.log('Cancel');
},
});
// partUpdates()
}
if (res && res === 'OPEN_ALL_UPDATE') {
console.log('OPEN_ALL_UPDATE')
// 全量更新
}
} catch (error) {
console.error('checkVersionERROR', error)
}
}
function checkVersion(params) {
return new Promise((resolve, reject) => {
const currentVersion = remote.app.getVersion()
// 獲取最新版本號
downloadFile(remoteYmlURL, localYmlUrl).then(res => {
const remoteVersion = JSON.stringify(res.data).split('\\n')[0].split(' ')[1]
const remoteVersionArr = remoteVersion.split('.')
const currentVersionArr = currentVersion.split('.')
// 0.1.1 Y和Z比較來開啟增量更新 1.1.1 X比較來開啟全量更新
if (Number(remoteVersionArr[0]) > Number(currentVersionArr[0])) {
// 開啟全量更新
return resolve('OPEN_ALL_UPDATE')
} else if (Number(remoteVersionArr[2]) > Number(currentVersionArr[2]) || Number(remoteVersionArr[1]) > Number(currentVersionArr[1])) {
// 開啟增量更新
return resolve('OPEN_PART_UPDATE')
} else {
console.log('無版本變動,不更新')
}
}).catch(e => {
console.error(e)
})
})
}
// src\main\controls\AppAutoUpdater.js
// 下載伺服器檔案包
// 本地解壓和備份,替換,重啟客戶端即可完成更新
// 增量更新
ipcMain.on('checkForPartUpdates', async (e, msg) => {
console.log('checkForPartUpdates', msg)
// if (isElectronDev) {
// console.log('開發模式不支援')
// return
// }
try {
if (fs.existsSync(`${localresourcePath}.back`)) { // 刪除舊備份
deleteDirSync(`${localresourcePath}.back`)
}
if (fs.existsSync(localresourcePath)) {
fs.renameSync(localresourcePath, `${localresourcePath}.back`); // 備份目錄
}
await downloadFile(remoteAppURL, appZipPath)
console.log('app.asar.unpacked.zip 下載完成')
fs.mkdirSync(localresourcePath) // 建立app來解壓用
try {
// 同步解壓縮
const unzip = new AdmZip(appZipPath)
unzip.extractAllTo(resourcePath, true)
console.log('app.asar.unpacked.zip 解壓縮完成')
console.log('更新完成,正在重啟...')
mainWindow.webContents.send('partUpdateReady')
setTimeout(() => {
app.relaunch(); // 重啟
app.exit(0);
}, 1800);
} catch (error) {
console.error(`extractAllToERROR: ${error}`);
}
// 更新視窗
// BrowserWindow.getAllWindows().forEach((win: any) => {
// win.webContents.reload()
// // remote.app.relaunch(); // 重啟
// // remote.app.exit(0);
// })
console.log('webContents reload完成')
} catch (error) {
console.error(`checkForPartUpdatesERROR`, error)
if (fs.existsSync(`${localresourcePath}.back`)) {
fs.renameSync(`${localresourcePath}.back`, localresourcePath);
}
}
})