You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Windows系统下Electron应用监听window-all-closed事件后无法驻留任务栏的解决方法

Windows系统下Electron应用监听window-all-closed事件后无法驻留任务栏的解决方法

这个问题的核心是Windows和macOS在Electron应用的默认行为上有本质差异:macOS的应用关闭窗口后会自动保留Dock图标,但Windows没有这个默认机制——要让Windows下的Electron应用在关闭所有窗口后驻留任务栏,必须手动添加**系统托盘(Tray)**作为应用的可视化入口,同时调整主进程的事件逻辑。

先分析你当前代码的问题:
你在window-all-closed事件里写了if (process.platform !== 'win32') app.quit(),这意味着Windows下关闭所有窗口时,主进程并不会退出(所以终端还在运行),但因为没有托盘图标,任务栏里看不到任何应用痕迹,导致你以为程序“消失”了。而当你换成darwin时,Windows下会触发app.quit(),主进程直接退出,终端也就停了。

下面是完整的解决步骤和修正后的代码:

1. 核心修改思路

  • 给Windows应用添加系统托盘图标,让用户能在任务栏看到并操作应用
  • 调整窗口关闭和托盘交互的逻辑,实现“关闭窗口后驻留托盘,点击托盘恢复窗口,右键菜单退出应用”的效果
  • 修正你代码里的小bug(nodeIntegrations拼写错误,应为nodeIntegration

2. 完整修改后的代码

// Main Process
const { app, BrowserWindow, Tray, Menu } = require("electron");
const path = require("path");

// 声明全局变量保存窗口和托盘实例
let win;
let tray;

function createWindow() {
  win = new BrowserWindow({
    width: 1200,
    height: 800,
    backgroundColor: "white",
    webPreferences: {
      // 修正拼写错误:nodeIntegrations → nodeIntegration
      nodeIntegration: true,
      // Electron 12+版本默认开启contextIsolation,需关闭才能启用nodeIntegration
      contextIsolation: false
    }
  });

  win.loadFile("index.html");
  // 如需打开开发者工具可取消注释
  // win.webContents.openDevTools();

  // 拦截窗口关闭事件:Windows下改为隐藏窗口,而非销毁
  win.on("close", (e) => {
    if (process.platform === "win32") {
      e.preventDefault(); // 阻止默认的窗口销毁行为
      win.hide(); // 隐藏窗口
      return false;
    }
  });
}

// 创建系统托盘
function createTray() {
  // 需准备一个托盘图标文件(如tray.ico)放在项目根目录,推荐用ico格式(Windows适配更好)
  // 可通过在线工具将普通图片转成ico格式,尺寸建议16x16/32x32
  tray = new Tray(path.join(__dirname, "tray.ico"));

  // 配置托盘右键菜单
  const contextMenu = Menu.buildFromTemplate([
    {
      label: "打开窗口",
      click: () => win.show() // 点击后恢复显示窗口
    },
    {
      label: "退出应用",
      click: () => {
        win.destroy(); // 彻底销毁窗口
        tray.destroy(); // 销毁托盘图标
        app.quit(); // 退出主进程
      }
    }
  ]);

  tray.setToolTip("我的Electron应用"); // 鼠标悬停托盘时的提示文本
  tray.setContextMenu(contextMenu); // 绑定右键菜单
  tray.on("click", () => win.show()); // 左键点击托盘直接恢复窗口
}

app.whenReady().then(() => {
  createWindow();
  // 仅在Windows系统下创建托盘
  if (process.platform === "win32") {
    createTray();
  }
});

app.on("window-all-closed", () => {
  // macOS下保持默认逻辑:关闭所有窗口后不退出,保留Dock图标
  if (process.platform === "darwin") {
    app.quit();
  }
  // Windows下主进程保持运行,依靠托盘驻留
});

app.on("activate", () => {
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow();
  } else {
    win.show();
  }
});

3. 关键细节说明

  • 托盘图标准备:你需要自己生成一个tray.ico文件放在项目根目录,没有图标的话Electron会用默认占位图标,可能显示异常。
  • 窗口关闭逻辑:我们拦截了窗口的close事件,将“销毁窗口”改为“隐藏窗口”,这样点击托盘就能快速恢复窗口,无需重新初始化;如果需要彻底销毁窗口,也可以选择销毁,然后点击托盘时调用createWindow()重建。
  • 主进程驻留控制:Windows下window-all-closed事件里不调用app.quit(),让主进程保持运行,同时托盘图标留在任务栏,用户随时可以通过托盘操作应用。
  • Node.js集成修正:你原代码里的nodeIntegrations是拼写错误,正确属性名是nodeIntegration;Electron 12+版本默认开启contextIsolation,需要手动关闭才能正常启用Node.js集成。

4. 测试效果

运行修改后的代码后:

  1. 打开应用窗口,正常使用
  2. 关闭窗口后,窗口消失,但任务栏右下角会出现你的托盘图标
  3. 左键点击托盘图标,窗口会立即重新显示
  4. 右键托盘图标选择“退出应用”,会彻底关闭应用,终端进程也会停止

这样就实现了和macOS类似的“关闭窗口后驻留任务栏”的效果。

火山引擎 最新活动