import {WebContents, app, dialog} from "electron"; import type { Details, RenderProcessGoneDetails, Event, BrowserWindow, } from "electron"; export interface UseProcessExceptionReturn { /** * Emitted when the renderer process unexpectedly disappears. This is normally because it was crashed or killed. * If a listener is not passed in, it will default to following the crash prompt * * @see https://www.electronjs.org/docs/latest/api/app#event-render-process-gone */ renderProcessGone: ( listener?: ( event: Event, webContents: WebContents, details: RenderProcessGoneDetails ) => void ) => void; /** * Emitted when the child process unexpectedly disappears. This is normally because it was crashed or killed. It does not include renderer processes. * If a listener is not passed in, it will default to following the crash prompt * * @see https://www.electronjs.org/docs/latest/api/app#event-child-process-gone */ childProcessGone: ( window: BrowserWindow, listener?: (event: Event, details: Details) => void ) => void; } export const useProcessException = (): UseProcessExceptionReturn => { const renderProcessGone = ( listener?: ( event: Event, webContents: WebContents, details: RenderProcessGoneDetails ) => void ) => { app.on("render-process-gone", (event, webContents, details) => { if (listener) { listener(event, webContents, details); return; } const message = { title: "", buttons: [], message: "", }; switch (details.reason) { case "crashed": message.title = "警告"; message.buttons = ["确定", "退出"]; message.message = "图形化进程崩溃,是否进行软重启操作?"; break; case "killed": message.title = "警告"; message.buttons = ["确定", "退出"]; message.message = "由于未知原因导致图形化进程被终止,是否进行软重启操作?"; break; case "oom": message.title = "警告"; message.buttons = ["确定", "退出"]; message.message = "内存不足,是否软重启释放内存?"; break; default: break; } dialog .showMessageBox({ type: "warning", title: message.title, buttons: message.buttons, message: message.message, noLink: true, }) .then((res) => { if (res.response === 0) webContents.reload(); else webContents.close(); }); }); }; const childProcessGone = ( window: BrowserWindow, listener?: (event: Event, details: Details) => void ) => { app.on("child-process-gone", (event, details) => { if (listener) { listener(event, details); return; } const message = { title: "", buttons: [], message: "", }; switch (details.type) { case "GPU": switch (details.reason) { case "crashed": message.title = "警告"; message.buttons = ["确定", "退出"]; message.message = "硬件加速进程已崩溃,是否关闭硬件加速并重启?"; break; case "killed": message.title = "警告"; message.buttons = ["确定", "退出"]; message.message = "硬件加速进程被意外终止,是否关闭硬件加速并重启?"; break; default: break; } break; default: break; } dialog .showMessageBox(window, { type: "warning", title: message.title, buttons: message.buttons, message: message.message, noLink: true, }) .then((res) => { // 当显卡出现崩溃现象时使用该设置禁用显卡加速模式。 if (res.response === 0) { if (details.type === "GPU") app.disableHardwareAcceleration(); window.reload(); } else { window.close(); } }); }); }; return { renderProcessGone, childProcessGone, }; };