You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 03:07:48