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

6tqwzwtp  于 12个月前  发布在  Electron
关注(0)|答案(9)|浏览(186)

我有一个Electron应用程序,可以打开不同的窗口。
在应用程序启动应用程序打开一组窗口(S)(加载相同的HTML和JS文件),但与参数更改每个窗口显示的信息。
范例:

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://path中传递参数是不起作用的。我在Electron文档或Internet上的其他地方找不到一个明确的解决方案来为我的渲染窗口设置参数。
我可以在窗口准备好后使用IPC通信,但它似乎有点太复杂了,直到我只想传递一个变量给我的子视图。
附言:老实说,我的应用程序是用React/Redux构建的,我想传递给view的参数是redux store键来监听这个视图。

kmb7vmvb

kmb7vmvb1#

几种方法:

loadURL查询字符串

其他人发布的查询字符串方法似乎工作得很好。它甚至可能是最简单的。

additional参数

Electron的文档说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 Main / Render

就像你说的,这对你想做的事情来说似乎很复杂,但也许这会有所帮助:

主要

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


这种方式允许您发送字符串以外的数据。

jgzswidk

jgzswidk2#

根据atom源代码,query string方法是一种非常简单的可靠方法,特别是当我们只需要传递一个唯一的字符串参数时:

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

wgmfuz8q

wgmfuz8q3#

使用查询字符串沿着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)}});

个字符

js81xvg6

js81xvg64#

我们可以注入JavaScript代码执行(在窗口did-finish-load事件上)并触发react重新渲染正确的redux状态部分。但它需要渲染过程中的额外生命周期步骤。
在“local filepath”中使用hash或query听起来有点奇怪,但在我的情况下,它是有意义的,因为hash描述了在这个窗口(file://which-code-to-load#which-content)中要考虑的redux商店分支。
所以,即使我现在对这种方法不完全放心,我也会采取第二种选择。
很遗憾,API没有提供任何方法在窗口打开时从主进程声明全局变量。我将发布一个功能请求。

jqjz2hbq

jqjz2hbq5#

实际上使用invoke和handle组合也可以工作。在我的例子中,我特别需要在一开始就建立连接。
前负荷

const { ipcRenderer } = require('electron')

window.addEventListener('DOMContentLoaded', () => {
  ipcRenderer.invoke('init').then(res => {
    window.alert(res)
    // render(e(App, {}), elem)
  })
})

字符串
而在主

const { ipcMain } = require('electron')

ipcMain.handle('init', async () => {
  return 'Abc'
})


你甚至可以尝试通过ipcRenderer.sendSync进行同步调用,也许这会更快,但我还没有尝试过。

biswetbf

biswetbf6#

举例来说:

流程脚本

在你的主脚本中写上:

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

字符串

窗口脚本

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

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

v9tzhpje

v9tzhpje7#

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

global.id = 1;

字符串
渲染器处理器:

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

iswrvxsc

iswrvxsc8#

如果您正在创建BrowserWindow的新示例,则查询参数似乎不起作用,至少在以下版本中是这样:

"electron": "^26.2.2",
"nextron": "^8.12.0",

字符串
我发现的解决方法是通过additionalArguments传递参数

webPreferences: {
        additionalArguments: [
          `--metadata=${JSON.stringify(arg.data)}`,
        ],
      },


然后在预加载脚本上

const metadata = process.argv.filter((arg) => arg.startsWith('--metadata='))[0]?.split('=')?.[1]
const data = JSON.parse(metadata || '{}')

contextBridge.exposeInMainWorld('appInfo', {
  metadata: data,
})


然后你可以把它放在你的组件上,

global.appInfo.metadata

de90aj5v

de90aj5v9#

不幸的是,它看起来相当复杂,你可能无法以一种好的方式向你在electron中呈现的.html中添加变量。
当然-你可以使用url,但它会减慢启动速度(vy秒),或者你可以在BrowserWindo中执行JavaScript,这也会减慢启动速度。
唯一的方法是IPC和离开JavaScript不可知的变量从主进程。

相关问题