在 Electron 中生成一个子进程
Spawn a child process in Electron
我正在使用 Node v6.2.2 和 Electron v1.2.5。
我有一个基于 Electron 构建的小应用程序,现在我需要 fork
进程到 运行 另一个节点进程中的一些长 运行ning 任务但它似乎不起作用,当我查看 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 时,它似乎工作得很好。
我已经尝试了很多示例,但其中 none 似乎有效,另一种可能性是我需要在 Electron 中做一些特殊的事情才能使其正常工作,但我不知道。
如果您使用 --asar
标志编译 Electron,based on the docs 那将是一个问题。
还有 this issue 你不能将 stdio 附加到父级的地方。所以假设有一个分离的标准输入输出不是一个交易破坏者,你可以尝试 { stdio: 'ignore' }
.
终于解决了
我解决这个问题的方法正好相反,NodeJS 在生产机器上可用,所以我只写了一个 start.js
脚本,基本上生成一个子进程到 运行 Electron 和父进程 我正在 运行ning 这个漫长的 运行ning 任务,最后我使用 IPC 在两个进程之间进行通信。
另外,你可以在 electron 进程中 fork 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
})
如果此答案是可移植的 .exe,则它适合您的应用程序。我自己没有使用过可安装的,所以对此了解不多。
边开发边创建子进程真的很容易。最简单的是使用 Node 的 child_process
中的 fork()
(尽管我们可以根据需要使用任何 spawn/exec/execFile... 等等)。
当我们将应用程序打包为包含打包文件的可执行文件时,困难的部分就来了 "app.asar"。
关键是,你明白"app.asar"是什么吗? "app.asar" 乍一看就像一个普通的捆绑文件,但它实际上是一个 虚拟目录,这意味着您可以像访问任何其他目录一样在其中遍历, 也许只需将其视为目录名称即可。如果您在电子代码的主进程下执行 __dirname
,您会看到该位置为 '/path/to/app.asar'.
你怎么看"app.asar"里面的东西? - reference
fs.readdirSync('/path/to/app.asar')
回答
您需要 bundle/copy 文件(该文件将 运行 在一个单独的进程中,例如文件名是:"child.process.js")分别放入您的打包程序所在的文件夹中(例如: electron-builder) 正在创建 EXE。假设您将所有内容打包到 "dist" 文件夹下,那么此 dist 文件夹应该包含文件 child.process.js。现在这个 "dist" 文件夹本身将变成 "app.asar".
当您为 fork()
指定 child.process.js
的路径时,如果文件 "child.process.js" 直接位于 dist
中,请将其命名为:
fork(path.join(__dirname, 'child.process.js'))
如果它存在于子目录下,请给出适当的路径。
有趣的是,上面的代码在将其用作可移植 EXE 和开发时都有效(如果将所有主要进程文件捆绑到一个文件中。)
我花了 3 天时间才弄明白这个问题。在测试 EXE 时我是如何进行调试的?我使用 fs
写入文件,然后打开它们并读取它们的内容。当我打印 fs.readdirSync('/path/to/app.asar')
的输出时,我才意识到解决方案。有趣的是我有两个 dist 文件夹,我正在为本地开发 dist 打包我的子文件,但没有为我打包应用程序的 dist 打包。
希望这对某人有所帮助!
我正在使用 Node v6.2.2 和 Electron v1.2.5。
我有一个基于 Electron 构建的小应用程序,现在我需要 fork
进程到 运行 另一个节点进程中的一些长 运行ning 任务但它似乎不起作用,当我查看 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 时,它似乎工作得很好。
我已经尝试了很多示例,但其中 none 似乎有效,另一种可能性是我需要在 Electron 中做一些特殊的事情才能使其正常工作,但我不知道。
如果您使用 --asar
标志编译 Electron,based on the docs 那将是一个问题。
还有 this issue 你不能将 stdio 附加到父级的地方。所以假设有一个分离的标准输入输出不是一个交易破坏者,你可以尝试 { stdio: 'ignore' }
.
终于解决了
我解决这个问题的方法正好相反,NodeJS 在生产机器上可用,所以我只写了一个 start.js
脚本,基本上生成一个子进程到 运行 Electron 和父进程 我正在 运行ning 这个漫长的 运行ning 任务,最后我使用 IPC 在两个进程之间进行通信。
另外,你可以在 electron 进程中 fork 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
})
如果此答案是可移植的 .exe,则它适合您的应用程序。我自己没有使用过可安装的,所以对此了解不多。
边开发边创建子进程真的很容易。最简单的是使用 Node 的 child_process
中的 fork()
(尽管我们可以根据需要使用任何 spawn/exec/execFile... 等等)。
当我们将应用程序打包为包含打包文件的可执行文件时,困难的部分就来了 "app.asar"。
关键是,你明白"app.asar"是什么吗? "app.asar" 乍一看就像一个普通的捆绑文件,但它实际上是一个 虚拟目录,这意味着您可以像访问任何其他目录一样在其中遍历, 也许只需将其视为目录名称即可。如果您在电子代码的主进程下执行 __dirname
,您会看到该位置为 '/path/to/app.asar'.
你怎么看"app.asar"里面的东西? - reference
fs.readdirSync('/path/to/app.asar')
回答
您需要 bundle/copy 文件(该文件将 运行 在一个单独的进程中,例如文件名是:"child.process.js")分别放入您的打包程序所在的文件夹中(例如: electron-builder) 正在创建 EXE。假设您将所有内容打包到 "dist" 文件夹下,那么此 dist 文件夹应该包含文件 child.process.js。现在这个 "dist" 文件夹本身将变成 "app.asar".
当您为 fork()
指定 child.process.js
的路径时,如果文件 "child.process.js" 直接位于 dist
中,请将其命名为:
fork(path.join(__dirname, 'child.process.js'))
如果它存在于子目录下,请给出适当的路径。
有趣的是,上面的代码在将其用作可移植 EXE 和开发时都有效(如果将所有主要进程文件捆绑到一个文件中。)
我花了 3 天时间才弄明白这个问题。在测试 EXE 时我是如何进行调试的?我使用 fs
写入文件,然后打开它们并读取它们的内容。当我打印 fs.readdirSync('/path/to/app.asar')
的输出时,我才意识到解决方案。有趣的是我有两个 dist 文件夹,我正在为本地开发 dist 打包我的子文件,但没有为我打包应用程序的 dist 打包。
希望这对某人有所帮助!