问题
I have an Electron app that can open different windows.
On app launch the app open a set of window(s) (that load the same HTML and JS files) but with params to change each window displayed infos.
Example :
app.on('ready', async () => {
...
// open window for stuff 1
win1 = new BrowserWindow({
width: 1024,
height: 728
});
win1.loadURL(`file://${__dirname}/app/app.html?id=1`);
// open window for stuff 2
win2 = new BrowserWindow({
width: 1024,
height: 728
});
win2.loadURL(`file://${__dirname}/app/app.html?id=2`);
Obviously passing params in file:// path doesn't work. I can't find a clear solution in Electron documentation or elsewhere on Internet to condition my rendered window to a param.
I can probably use IPC communication after window ready but it seems a little bit too complicated until I just want pass a variable to my child view.
P.S. : to be totally honest my application is built with React/Redux and the param I want to pass to view is the redux store key to listen for this view.
回答1:
A few methods:
loadURL Query String
The query string method others have posted seems to work fine. It might even be the easiest.
additionalArguments
Electron's documentation says additionalArguments
is:
Useful for passing small bits of data down to renderer process preload scripts.
Main
const win = new BrowserWindow({
width: 800,
height: 600,
backgroundColor: '#000000'
webPreferences: {
additionalArguments: ["myvarvalue", "secondvarvalue", "--another=something"]
}
});
Renderer
window.process.argv
is going to look something like:
["--num-raster-threads=2",
"--enable-gpu-memory-buffer-compositor-resources",
"--enable-gpu-async-worker-context",
...
"--renderer-client-id=4",
"myvarvalue",
"secondvarvalue",
"--another=something"]
It will append an array of strings. You could do something window.process.argv.slice(-3)
to grab the last items in the array.
IPC Main / Render
Like you said, it seems complicated for what you are trying to do, but maybe this helps:
Main
const { ipcMain } = require('electron');
var mainProcessVars = {
somevar: "name",
anothervar: 33
}
ipcMain.on('variable-request', function (event, arg) {
event.sender.send('variable-reply', [mainProcessVars[arg[0]], mainProcessVars[arg[1]]]);
});
Renderer
const { ipcRenderer } = electron;
electron.ipcRenderer.send('variable-request', ['somevar', 'anothervar']);
ipcRenderer.on('variable-reply', function (event, args) {
console.log(args[0]); // "name"
console.log(args[1]); // 33
});
This way allows you to send data besides strings.
回答2:
According atom source code the query string method is a reliable way to do that very simply, especially when we only need to pass a unique string param:
// main process
win1.loadURL(`file://${__dirname}/app/app.html?id=${id}`);
// rendered process
console.log(global.location.search);
https://github.com/electron/electron/issues/6504
回答3:
Using query string along with win.loadFile()
,
// main process or renderer process 1
data = {"age": 12, "healthy": true}
let win = new BrowserWindow({
webPreferences: {
nodeIntegration: true
}
});
win.loadFile("public/print.html", {query: {"data": JSON.stringify(data)}});
// renderer process 2
const querystring = require('querystring');
let query = querystring.parse(global.location.search);
let data = JSON.parse(query['?data'])
回答4:
We can inject Javascript code execution (on window did-finish-load
event) and trigger react re-rendering with correct redux state portion. But it requires additional lifecycle step in rendered process.
Using hash or query in "local filepath" sounds a little bit weird but in my case it take sense since the hash describe the redux store branch to take in consideration in this window (file://which-code-to-load#which-content
).
So even if i'm not totally at ease with this approach right now I'll take the second option.
It's a shame that the API doesn't provide any way to declare global vars from main process on window opening. I'll post a feature request.
回答5:
Unfortunately, it seems pretty complicated. You probably won't be able to add variables to .html you render in electron in a nice way.
Of course - you can use url but it slows down booting very much (vy seconds) or you can execute Javascript in BrowserWindo, which also slows boot down.
The only way is the IPC and leaving javascript .html agnostic to variables from main process. Very sad though..
回答6:
For example:
Process script
In your main script write:
global.varsForWindow = {
platform: process.platform
};
Window script
Where you need it in a window script:
var varsFromMainScript = require('electron').remote.getGlobal('varsForWindow');
console.log(varsFromMainScript.platform);
回答7:
You can share data between main and renderer processor using global
variable:
Main processor:
global.id = 1;
Renderer processor:
let id = remote.getGlobal('id');
来源:https://stackoverflow.com/questions/38335004/how-to-pass-parameters-from-main-process-to-render-processes-in-electron