Electron 应用关闭确认弹窗无法阻止程序退出问题求助
问题根因
- 核心问题是
dialog.showMessageBox为异步API,Electron 的close事件不会等待异步回调执行完成就会继续走默认关闭流程,你将e.preventDefault()放在then异步回调中执行时,窗口已经进入销毁阶段,阻止操作完全不生效。 - 逻辑判断错误:当前代码中用户点击「确认退出(Yes,对应索引0)」时你执行了阻止关闭的操作,和预期功能完全相反。
- 缺少重复触发防护:如果后续手动调用窗口关闭方法,会再次触发
close事件,导致重复弹出确认框。
修复方案
首先在close事件的同步回调阶段就先阻止默认关闭行为,等拿到用户的选择结果后,再通过标记变量控制是否真正执行关闭操作,修复后代码如下:
// 标记是否已经确认要关闭,避免重复触发确认弹窗 let isConfirmedToClose = false; win.on('close', function (e) { if (!isConfirmedToClose) { // 同步执行阻止关闭,必须放在当前层级,不能放到异步回调中 e.preventDefault(); const { dialog } = require('electron'); dialog.showMessageBox(this, { type: 'question', buttons: ['确认退出', '取消'], title: '退出确认', message: '确定要退出应用吗?' }).then(res => { // 用户点击了确认退出按钮 if (res.response === 0) { isConfirmedToClose = true; // 手动调用关闭,此时标记为已确认,不会再次触发弹窗 win.close(); } }); } });
注意事项
如果你不需要考虑主进程阻塞的问题,也可以直接使用dialog.showMessageBoxSync同步弹窗API,直接阻塞close事件流程,代码会更简洁:
win.on('close', function (e) { const { dialog } = require('electron'); const res = dialog.showMessageBoxSync(this, { type: 'question', buttons: ['确认退出', '取消'], title: '退出确认', message: '确定要退出应用吗?' }); // 点击了取消,阻止关闭 if (res === 1) { e.preventDefault(); } });
内容的提问来源于stack exchange,提问作者Pavel
相关产品推荐
相关产品推荐

