在我的应用程序中,我有两个窗口:mainWindow和actionWindow。在我的 mainWindow 上,当 actionWindow 关闭时,我使用侦听器从主进程接收消息。ipcRenderer.on然而,该消息没有通过。
用于mainWindow控制在 上发生的操作actionWindow(例如导航到 URL、远程关闭窗口……)。我想赋予用户手动移动和关闭的权力actionWindow,这就是为什么它的标题栏可见且可用。
我通过预加载文件中的 contextBridgeipcRenderer.invoke公开双向通信并公开给 mainWindow 的渲染器。ipcRenderer.on
这就是代码的样子(基于vite-electron-builder 模板)
主要流程
const mainWindow = new BrowserWindow({
show: false, // Use 'ready-to-show' event to show window
webPreferences: {
nativeWindowOpen: true,
webviewTag: false,
preload: join(__dirname, "../../preload/dist/index.cjs"),
},
});
const actionWindow = new BrowserWindow({
// some props
})
actionWindow.on("close", () => {
console.log("window closed")
mainWindow.webContents.send("closed", { message: "window closed" });
});
Run Code Online (Sandbox Code Playgroud)
预载
contextBridge.exposeInMainWorld("ipcRenderer", {
invoke: ipcRenderer.invoke,
on: ipcRenderer.on,
});
Run Code Online (Sandbox Code Playgroud)
渲染器(主窗口)
window.ipcRenderer.on("closed", () => {
console.log("message received")
// do something
});
Run Code Online (Sandbox Code Playgroud)
我知道一个事实
invoke工作及其在主进程上触发的操作按预期在 actionWindow 上执行+响应也返回到渲染器。close看到日志window closedmessage received没有出现在我的开发工具控制台中对我来说这意味着
mainWindow.webContents.send不起作用 -> 消息从未发送window.ipcRenderer.on不起作用 -> 消息永远不会到达目的地因此,要么我的代码有问题,要么 Electron 最近对其中一种我不知道的方法施加了一些限制。
有任何想法吗?如果有比 IPC 更智能的方法来做到这一点,我也愿意这样做。
好吧,经过几个小时的搜索、尝试和痛苦,我(几乎是意外地)找到了解决我的问题的方法。on当您从渲染器调用该方法时,电子似乎不再执行任何操作。再次研究有关 contextBridge 的文档,invoke我发现我暴露给on渲染器的方式被认为是糟糕的代码。更安全的方法是为您想要使用的每个 ipc 通道公开一个函数。在我使用 TypeScript 的情况下,它看起来像这样:
预载
contextBridge.exposeInMainWorld("ipcRenderer", {
invokeOpen: async (optionsString: string) => {
await ipcRenderer.invoke("open", optionsString);
},
onClose: (callback: () => void) => {
ipcRenderer.on("closed", callback);
},
removeOnClose: (callback: () => void) => {
ipcRenderer.removeListener("closed", callback);
},
});
Run Code Online (Sandbox Code Playgroud)
渲染器(主窗口)
window.ipcRenderer.onClose(() => {
// do sth
});
window.ipcRenderer.invokeOpen(JSON.stringify(someData)).then(() => {
// do sth when response came back
});
Run Code Online (Sandbox Code Playgroud)
注意:为了通过在主窗口的每个渲染上创建侦听器来防止内存泄漏,您还必须使用提供的清理功能removeOnClose(请参阅预加载)。根据前端框架的不同,此功能的使用方法也有所不同。使用 React 看起来像这样:
const doSth= () => {
console.log("doing something")
...
};
useEffect(() => {
window.ipcRenderer.onClose(doSth);
return () => {
window.ipcRenderer.removeOnClose(doSth);
};
}, []);
Run Code Online (Sandbox Code Playgroud)
这不仅是一个更安全的解决方案,而且它实际上突然起作用了:O 使用清理功能我们还可以处理泄漏。
| 归档时间: |
|
| 查看次数: |
979 次 |
| 最近记录: |