macOS下Electron Builder更新异常:陷入更新循环问题求助
macOS下Electron Builder更新循环问题的解决方案
方案1:添加更新加载视图,阻止用户手动重启
在触发更新并退出应用前,显示一个置顶的加载提示窗口,明确告知用户正在更新,避免用户过早重启应用触发循环。
主进程实现代码
const { app, BrowserWindow, autoUpdater } = require('electron'); const path = require('path'); // 监听更新下载完成事件 autoUpdater.on('update-downloaded', () => { // 创建更新加载窗口(无框架、不可调整大小、置顶) const updateLoadingWin = new BrowserWindow({ width: 320, height: 160, frame: false, resizable: false, alwaysOnTop: true, webPreferences: { contextIsolation: false, // 根据你的Electron配置调整,若开启contextIsolation需用preload脚本 nodeIntegration: true } }); // 加载自定义的更新提示页面 updateLoadingWin.loadFile(path.join(__dirname, 'update-loading.html')); // 触发更新安装并退出当前应用 autoUpdater.quitAndInstall(); // 应用退出时销毁加载窗口 app.once('before-quit', () => { updateLoadingWin.destroy(); }); });
自定义更新提示页面(update-loading.html)
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { width: 100%; height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; } .spinner { width: 48px; height: 48px; border: 4px solid #e0e0e0; border-top-color: #2196F3; border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } .tip { margin-top: 20px; color: #333; font-size: 14px; } </style> </head> <body> <div class="spinner"></div> <p class="tip">应用正在后台更新,请不要手动重启</p> </body> </html>
方案2:捕获待处理更新状态,限制应用启动
通过创建临时标记文件的方式,在应用启动时检测是否有正在进行的更新任务,若有则提示用户并退出应用,避免进入更新循环。
主进程实现代码
const { app, BrowserWindow, dialog, autoUpdater } = require('electron'); const path = require('path'); const fs = require('fs'); // 定义更新状态标记文件路径(存在则表示更新中) const updateLockFile = path.join(app.getPath('userData'), 'update-in-progress.lock'); app.on('ready', () => { // 启动时检查更新标记 if (fs.existsSync(updateLockFile)) { const fileStats = fs.statSync(updateLockFile); // 若标记文件存在超过60秒,判定更新已完成或失败,删除标记 if (Date.now() - fileStats.mtime.getTime() > 60000) { fs.unlinkSync(updateLockFile); } else { // 提示用户更新中并退出 dialog.showMessageBoxSync({ type: 'info', title: '更新进行中', message: '应用正在后台更新,请稍后再启动', buttons: ['确定'] }); app.quit(); return; } } // 正常创建主窗口 const mainWindow = new BrowserWindow({ // 你的窗口配置 webPreferences: { contextIsolation: true, preload: path.join(__dirname, 'preload.js') } }); mainWindow.loadFile('index.html'); // 更新下载完成时创建标记文件 autoUpdater.on('update-downloaded', () => { fs.writeFileSync(updateLockFile, ''); autoUpdater.quitAndInstall(); }); // 应用正常退出时删除标记文件 app.on('will-quit', () => { if (fs.existsSync(updateLockFile)) { fs.unlinkSync(updateLockFile); } }); });
注意事项
- 针对Electron 24版本,
contextIsolation默认开启,若需在渲染进程使用Node API,建议通过preload脚本实现,避免直接开启nodeIntegration带来的安全风险。 - 方案2中的超时时间可根据你的实际更新耗时调整(当前设为60秒)。
内容的提问来源于stack exchange,提问作者Trofin
相关产品推荐
相关产品推荐

