Electron主进程里怎么监听窗口关闭事件?

一奕卓 阅读 30

我在用 Electron 开发桌面应用,想在用户点击窗口右上角关闭按钮时做一些清理操作,比如保存数据。但不知道怎么在主进程里正确监听这个事件。

试过用 mainWindow.on('close', ...),但好像没生效,或者触发时机不对?是不是应该用别的事件?

这是我的窗口创建代码:

const mainWindow = new BrowserWindow({
  width: 800,
  height: 600,
  webPreferences: {
    preload: path.join(__dirname, 'preload.js')
  }
});

mainWindow.on('close', () => {
  console.log('窗口要关闭了');
  // 想在这里做点事
});
我来解答 赞 10 收藏
二维码
手机扫码查看
2 条解答
西门恩硕
你的代码写法是对的,mainWindow.on('close', ...) 确实能监听到关闭事件。但你说没生效,大概率是下面几个原因:

1. 主进程的 console.log 你可能没看到

主进程的日志不会出现在渲染进程的 DevTools 里。你需要确认下是不是在终端或者日志文件里查看。主进程崩溃或者日志级别不对都可能导致你看不到输出。2. 异步操作没执行完窗口就关了

这是最常见的问题。如果你这样写:

mainWindow.on('close', (event) => {
console.log('窗口要关闭了');
saveData(); // 假设这是个异步函数
});
// 窗口直接关了,saveData() 可能还没执行完


因为 close 事件的默认行为是立即关闭窗口,你的异步清理代码根本来不及跑完。

正确的做法是用 preventDefault 阻止默认关闭,然后手动控制关闭时机:

mainWindow.on('close', (event) => {
// 阻止默认的关闭行为
event.preventDefault();

// 这里是异步清理操作
saveData().then(() => {
console.log('数据保存完成,可以关闭了');
// 手动触发真正的关闭
mainWindow.destroy();
}).catch((err) => {
console.error('保存失败:', err);
// 即使失败也关闭
mainWindow.destroy();
});
});


3. 还有个可能的坑:别把 BrowserWindow 的 close 和 webContents 的 close 搞混了

有些人会写成 mainWindow.webContents.on('close', ...),这个事件的触发时机不太一样,是在所有窗口关闭前触发,容易出问题。咱们通常监听 BrowserWindow 本身的 close 事件就够了。



总结一下,你的写法没问题,但需要加上 event.preventDefault() 来阻止立即关闭,然后在你需要的操作完成后调用 mainWindow.destroy() 真正关闭窗口。

如果你只是做同步的清理操作,比如写文件、设置状态之类的,直接写就行,不用担心异步问题。只有涉及 Promise 或者回调的异步操作时才需要上述那套流程。
点赞
2026-03-11 19:06
设计师晓芳
close 事件没问题,但你想阻止关闭做清理的话得调 event.preventDefault(),完事再 mainWindow.destroy()

mainWindow.on('close', (event) => {
event.preventDefault(); // 阻止直接关闭
// 做你的清理操作...
saveData().then(() => {
mainWindow.destroy(); // 完事后真正关闭
});
});


如果不需要阻止关闭,只是监听,用 closed 事件也行,那是窗口关掉之后触发的。
点赞 2
2026-03-01 14:11