electron子进程使用主进程模块报错,引入就报错
const { BrowserWindow } = require('@electron/remote')
问题出现在子进程A中使用BrowserWindow创建了一个窗口页面子进程B,在子进程B中需要dialog,使用导入库const { dialog } = require('@electron/remote')报错如下
关键点
子进程A的界面在主进程中创建正常打开,不报错。
子进程B的界面是在子进程A创建正常打开,不报错。
但是在子进程B是引入dialog或者BrowserWindow就报错
主进程main.js关键代码
const { app, BrowserWindow,Menu } = require('electron')
app.commandLine.appendSwitch('--js-flags', '--harmony_proxies');
const path = require('path')
const createWindow = () => {
const mainWindow = new BrowserWindow({
width: 1280,
height: 800,
webPreferences: {
//preload: path.join(__dirname, 'preload.js'),
nodeIntegration:true, //允许渲染进程使用node.js
contextIsolation:false, //允许渲染进程使用node.js
// 开启remote
enableRemoteModule:true
},
})
require("@electron/remote/main").initialize();
require("@electron/remote/main").enable(mainWindow.webContents);
mainWindow.loadFile('index.html')
// 打开开发工具
// mainWindow.webContents.openDevTools()
}
进程A关键代码
window.onload = function () {
const { BrowserWindow } = require('@electron/remote')
//download
document.getElementById("download").onclick = function () {
newWin1 = new BrowserWindow({
width: 750,
height: 500,
backgroundColor: '#fff',
//resizable:false,
webPreferences: {
//preload: path.join(__dirname, 'preload.js'),
nodeIntegration: true, //允许渲染进程使用node.js
contextIsolation: false, //允许渲染进程使用node.js
// 开启remote
enableRemoteModule: true
},
});
require("@electron/remote/main").enable(newWin1.webContents)
newWin1.loadFile("./addons/download/download.html");
require("@electron/remote/main").enable(webContents)
newWin1.on("closed", () => {
newWin = null;
});
};
};
进程B关键代码
var { clipboard } = require("electron");
const { BrowserWindow } = require('@electron/remote')
document.getElementById("button_choose").onclick = function () {
console.log("开始");
};
有人知道吗
这个问题可能是因为在 Electron 中,每个渲染进程(如你的进程 A 和进程 B)都是相互独立的,它们不能直接访问主进程的模块。为了允许渲染进程访问主进程模块,Electron 引入了 Remote 模块,Remote 模块使得在渲染进程中可以使用主进程模块。
在你的进程 A 中,你已经使用 Remote 模块来访问 BrowserWindow 模块。但是,在你的进程 B 中,你使用的是 require('@electron/remote') 模块来访问主进程的 dialog 模块,这是不正确的。
为了在渲染进程中使用主进程的模块,你需要使用 Electron Remote 模块来从主进程中获取对话框模块,具体代码如下:
const { remote } = require('electron');
const { dialog } = remote;
// 这里就可以正常使用 dialog 模块了
dialog.showOpenDialog({ properties: ['openFile', 'multiSelections'] });
同时,为了防止你的应用程序容易受到安全漏洞攻击,最好不要在渲染进程中使用 nodeIntegration: true 和 contextIsolation: false 等选项。你可以使用 preload 选项和一个专用的 preload 脚本来允许渲染进程与主进程进行通信。具体做法是在渲染进程中设置 preload 选项指向一个 js 文件,该文件将在渲染进程初始化时被注入,从而允许渲染进程与主进程通信。如下所示:
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
然后,在 preload.js 中可以使用 contextBridge 和 ipcRenderer 模块来定义一个安全的 API,以便渲染进程与主进程进行通信。具体代码可以参考以下示例:
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('myAPI', {
send: (channel, data) => {
let validChannels = ['toMain'];
if (validChannels.includes(channel)) {
ipcRenderer.send(channel, data);
}
},
receive: (channel, func) => {
let validChannels = ['fromMain'];
if (validChannels.includes(channel)) {
ipcRenderer.on(channel, (event, ...args) => func(...args));
}
}
});
然后,在渲染进程中,可以使用 window.myAPI.send() 和 window.myAPI.receive() 方法与主进程进行通信。这样可以大大提高你的应用程序的安全性。
不知道你这个问题是否已经解决, 如果还没有解决的话: