在Electron中产生一个子进程

时间:2016-07-03 17:04:34

标签: electron

我使用的是Node v6.2.2和Electron v1.2.5。

我有一个小的应用程序,我已经建立在Electron之上,现在我需要fork进程在另一个节点进程中运行一些长时间运行的任务,但它似乎不是工作,当我查看ChildProcess对象时,我可以看到在参数spawnargs [0]中使用电子可执行文件而不是节点进行初始化,所以我所做的就是我试图使用spawn相反,但它无法正常工作。

以下是我用spawn进程(生活文件./modules/tester.js)中的代码:

const {spawn} = require('child_process');

var child = spawn("node", ["worker.js"], { stdio: ['inherit', 'inherit', 'inherit', 'ipc'] });

const self = {};

self.start = () => {
    console.log("start");
    child.send("ping");
};

以下是我用于worker.js文件的代码:

process.on("message", (data) => {
    console.log(data);
    console.log("pong");
});

最后这就是我消费它的方式。

const {app} = require("electron");

const tester = require("./modules/tester");

app.on("ready", () => {
    tester.start();
});

也许我做错了,但我不这么认为,因为当我使用nodejs时,似乎工作正常。

我尝试过很多例子,但似乎没有一个例子可行,另一种可能性是我需要在Electron做一些特别的工作,但是我不知道。

4 个答案:

答案 0 :(得分:5)

如果您使用--asar标记编译Electron,based on the docs这将是一个问题。

还有this issue您无法将stdio附加到父级。因此,假设有一个独立的stdio不是一个交易破坏者,你可以尝试{ stdio: 'ignore' }

答案 1 :(得分:3)

最后,我已经解决了。

我解决这个问题的方法恰恰相反,NodeJS在生产机器上可用,所以我只写了一个start.js脚本,它基本上产生了一个子进程来运行Electron和父进程I'我正在运行这个长期运行的任务,最后我使用IPC在两个进程之间进行通信。

答案 2 :(得分:1)

另外,你可以在电子过程中分叉nodejs文件:

let serverProc = require('child_process').fork(
  require.resolve('./server.js'),
  ['--key', 'value'], // pass to process.argv into child
  {
    // options
  }
)
serverProc.on('exit', (code, sig) => {
  // finishing
})
serverProc.on('error', (error) => {
  // error handling
})

答案 3 :(得分:1)

如果它是可移植.exe,则此答案将适合您的应用。我自己还没有安装可安装的软件,所以对此了解不多。

在进行开发的同时创建子进程非常容易。最简单的方法是使用Node fork()中的child_process(尽管我们可以根据需要使用spawn / exec / execFile ...等中的任何一种)。

当我们将应用程序打包为可执行文件(其中包含打包的文件为“ app.asar”)时,困难的部分来了。

关键是,您了解什么是“ app.asar”吗?乍一看,“ app.asar”看起来像是普通的捆绑文件,但实际上是一个虚拟目录,这意味着您可以像在任何其他目录中一样遍历文件,作为目录名称。如果您要在电子代码的主要处理过程中进行__dirname,您会看到该位置为'/ path / to / app.asar'

您如何查看“ app.asar”内部的内容? -reference

fs.readdirSync('/path/to/app.asar')

答案

您需要将文件(将在单独的进程上运行的文件,称文件名是“ child.process.js”)单独打包/复制到打包程序(例如:electron-builder)所在的文件夹中创建EXE。假设您将所有内容打包在“ dist”文件夹下,那么此dist文件夹应具有文件child.process.js。现在,此“ dist”文件夹本身将变为“ app.asar”。

当您为child.process.js指定fork()的路径并且如果文件“ child.process.js”直接位于dist内时,请像这样输入:

fork(path.join(__dirname, 'child.process.js'))

如果它在子目录下,请提供适当的路径。

有趣的是,以上代码在将其用作便携式EXE时以及在开发时均有效(如果将所有主要过程文件捆绑到一个文件中)。



我花了三天的时间才弄清楚。在测试EXE时如何进行调试?我用fs来写文件,然后打开它们并读取它们的内容。我仅在打印fs.readdirSync('/path/to/app.asar')的输出时才意识到解决方案。有趣的是,我有两个dist文件夹,我正在打包我的子文件供本地开发dist使用,但没有为我打包App的dist使用它。

希望这对某人有帮助!