在Windows上使用Electron和Node,如何终止一个已经启动的进程?

13

我正在Electron主进程中启动后台进程(在Windows上),类似于以下方式:

app_exe = require("child_process").spawn(
  "app.exe" ,
  [ "--params", ... ],
  { stdio: "ignore" }
);

这个能正常工作,我可以从进程管理器中看到:

enter image description here

但是当 Electron 关闭(.on("closed")on("window-all-closed"))时,我无法关闭进程。

我尝试使用 child.kill([signal]),但是使用 tree-killtaskkill 也无济于事:只有第一个进程(例如6036)被杀死,第二个进程(5760)仍然存在。

即使是 exec taskkill /F /T /PID 也无法杀死它。

唯一的方法是使用 exec taskkill /F /IM app.exe /T,但是这样我就无法运行两个实例的 Electron 应用程序。

我在 Windows 上的进程管理方面是否忽略了一些显而易见的东西?


2
你可以以某种方式获取子进程的PID吗?如果可以,你只需要调用process.kill(PID)即可。 - ChesuCR
你尝试过使用 on('will-quit') 代替 on('closed') 吗? - siniradam
3个回答

3
我在Windows 7机器上遇到了类似的问题。我认为更新的操作系统会自动关闭子进程。
我所做的是仅保存所生成进程的PID,并在所有窗口关闭时发送一个 SIGTERM 消息以终止它。现在,如果在Electron应用程序关闭之前进程以其他方式死亡,则操作系统可能已经回收了子进程的PID,因此为了更加健壮,我使用了find-process npm模块来确保我保存的PID与正确的进程关联。
const proc = cp.spawn("app.exe");

app.on("window-all-closed", async () => {
    const list = await require("find-process")("pid", proc.pid);
    app.quit();
    if (list[0] && list[0].name.toLowerCase() === "app.exe")
        process.kill(proc.pid);
});

现在,如果您的Electron应用程序没有正常退出(且上述代码未运行),则需要依赖另一种技术。
如果您控制将要生成的子进程,您可以尝试启动一个线程来监听或ping主进程。如果它没有看到主进程,则可以自我销毁。
如果您无法控制生成的应用程序,那么我就没了什么办法,但上述代码将处理大多数情况。

1

我曾经遇到完全相同的问题,在论坛上找不到任何问题/答案来解决这个问题。所以经过一些研究,我找到了一个简单的解决方法并分享给大家:

// Workaround to close all processes / sub-processes after closing the app
electron.app.once('window-all-closed', electron.app.quit);
electron.app.once('before-quit', () => {
    window.removeAllListeners('close');
});

对我来说,它完美地工作了,希望对你也是如此。


0
你可以尝试使用这段代码:
ipcMain.on('exampletab:close', () => {
    ipcMain.removeAllListeners();
    exampleWindow.close();
});

这段代码省了我很多时间。当您关闭子窗口时,请使用removeAllListeners()来删除之前关闭的窗口。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接