在Electron中产生一个子进程

Eya*_*nik 18 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");
};
Run Code Online (Sandbox Code Playgroud)

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

process.on("message", (data) => {
    console.log(data);
    console.log("pong");
});
Run Code Online (Sandbox Code Playgroud)

最后这就是我消耗它的方式.

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

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

app.on("ready", () => {
    tester.start();
});
Run Code Online (Sandbox Code Playgroud)

也许我做错了但是我不这么认为,因为当我使用nodejs它似乎工作得很好.

我尝试了很多例子但是它们似乎都不起作用,另一种可能性是我需要在Electron中做一些特别的工作,但是我不知道.

xyz*_*xyz 7

如果您的应用程序是可移植的 .exe,则此答案将适合您的应用程序。我自己没有使用过可安装的,所以对此不太了解。

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

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

关键是,你明白“app.asar”是什么吗?正常情况下,“app.asar”看起来像一个普通的捆绑文件,但它实际上是一个虚拟目录,这意味着您可以像处理任何其他目录一样在其中遍历,也许只需将其视为目录名称即可。__dirname如果您在电子代码的主流程下执行操作,您会看到该位置为'/path/to/app.asar'

你如何看到“app.asar”里面的内容?-参考

fs.readdirSync('/path/to/app.asar')
Run Code Online (Sandbox Code Playgroud)

回答

您需要将文件(将在单独的进程上运行的文件,假设文件名是:“child.process.js”)单独捆绑/复制到打包程序(例如:电子构建器)创建 EXE 的文件夹中。假设您将所有内容打包在“dist”文件夹下,那么这个 dist 文件夹应该包含文件 child.process.js。现在这个“dist”文件夹本身将变成“app.asar”。

child.process.js当您指定的路径时,fork()如果文件“child.process.js”直接位于 内部dist,则如下所示:

fork(path.join(__dirname, 'child.process.js'))
Run Code Online (Sandbox Code Playgroud)

如果它存在于子目录下,则给出适当的路径。

有趣的是,上面的代码在将其用作可移植 EXE 和开发时都有效(如果将所有主进程文件捆绑到一个文件中。)



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

希望这对某人有帮助!


Eya*_*nik 6

最后,我已经解决了。

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


Jos*_*osh 5

如果您正在使用--asar标志编译Electron,则基于可能存在问题的文档.

还有这个问题,你不能将stdio附加到父级.因此,假设有一个独立的stdio不是一个交易破坏者,你可以尝试{ stdio: 'ignore' }.