如何在Electron中将参数从主进程传递到渲染进程

时间:2016-07-12 17:01:13

标签: javascript electron

我有一个可以打开不同窗口的电子应用程序。

在应用程序启动时,应用程序打开一组窗口(加载相同的HTML和JS文件),但使用params更改显示信息的每个窗口。

示例:

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`);

显然在file://路径中传递params不起作用。 我无法在Electron文档或Internet上的其他地方找到明确的解决方案来将我渲染的窗口调整为参数。

我可以在窗口准备好之后使用IPC通信,但在我只想将变量传递给子视图之前,它看起来有点太复杂了。

P.S。 :说实话,我的应用程序是使用React / Redux构建的,我想传递给view的param是用于监听此视图的redux存储键。

7 个答案:

答案 0 :(得分:7)

根据原子源代码,查询字符串方法是一种非常简单的可靠方法,尤其是当我们只需要传递一个唯一的字符串参数时:

// 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

答案 1 :(得分:2)

一些方法:

loadURL查询字符串

The query string method others have posted seems to work fine。甚至可能是最简单的。

additionalArguments

电子文档说additionalArguments是:

  

用于将少量数据向下传递到渲染器进程预加载   脚本。

主要

const win = new BrowserWindow({
  width: 800,
  height: 600,
  backgroundColor: '#000000'
  webPreferences: {
    additionalArguments: ["myvarvalue", "secondvarvalue", "--another=something"]
  }
});

渲染器

window.process.argv看起来像:

["--num-raster-threads=2",
"--enable-gpu-memory-buffer-compositor-resources",
"--enable-gpu-async-worker-context",
...
"--renderer-client-id=4",
"myvarvalue",
"secondvarvalue",
"--another=something"]

它将附加一个字符串数组。您可以做一些window.process.argv.slice(-3)来获取数组中的最后一项。


IPC主/渲染

就像您说的那样,您尝试执行的操作似乎很复杂,但这也许会有所帮助:

主要

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]]]);
});

渲染器

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
});

通过这种方式,您可以发送字符串以外的数据。

答案 2 :(得分:0)

我们可以注入Javascript代码执行(在窗口did-finish-load事件上)并使用正确的redux状态部分触发反应重新渲染。但它需要在渲染过程中执行额外的生命周期步骤。

在“本地文件路径”中使用散列或查询听起来有点奇怪但在我的情况下它有意义,因为散列描述了在此窗口中考虑的redux存储分支(file://which-code-to-load#which-content)。

所以,即使我现在对这种方法并不完全放心,我也会选择第二种选择。

令人遗憾的是,API没有提供任何方法来在窗口打开时从主进程声明全局变量。我会发布一个功能请求。

答案 3 :(得分:0)

不幸的是,这似乎很复杂。您可能无法将变量添加到以电子方式呈现的.html中。

当然 - 你可以使用url,但它会减慢启动速度(vy秒),或者你可以在BrowserWindo中执行Javascript,这也会降低启动速度。

唯一的方法是IPC并将javascript .html与主进程中的变量无关。虽然非常难过..

答案 4 :(得分:0)

例如:

处理脚本

在主脚本中编写:

global.varsForWindow = {
    platform: process.platform
};

窗口脚本

在窗口脚本中需要的地方:

var varsFromMainScript = require('electron').remote.getGlobal('varsForWindow');
console.log(varsFromMainScript.platform);

答案 5 :(得分:0)

您可以使用global变量在主处理器和渲染器处理器之间共享数据:

主处理器:

global.id = 1;

渲染器处理器:

let id = remote.getGlobal('id');

答案 6 :(得分:0)

将查询字符串与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'])