【问题标题】:Handling NodeJS's child_process in electron app在电子应用程序中处理 NodeJS 的 child_process
【发布时间】:2018-02-26 01:51:40
【问题描述】:

所以我正在开发一个应在按下按钮时启动外部应用程序的电子应用程序。它可以工作,但如果我关闭该应用程序并再次按下按钮,它将启动该过程的几个实例。代码如下:

ipcMain.on("run_crystal", () => {
  var cp = require("child_process");
  executablePath = crystal + "\\CrystalDM\\Server\\CrystalDMServer.exe";
  var Server_child = cp.spawn(executablePath);
  executablePath = crystal + "\\CrystalDM\\Game\\CrystalDM.exe";
  var parameters = ["test"];
  var options = {cwd:crystal+"\\CrystalDM\\Game"};
  console.log("a intrat in start game si urmeaza sa ruleze " + executablePath)
  var Game_child = cp.execFile(executablePath, parameters, options, (error, stdout, stderr) =>{
    console.log(stdout)
    Game_child.kill("SIGINT");
    Server_child.kill("SIGINT");
    delete Game_child;
    delete Server_child;
    delete cp;
  });
});

【问题讨论】:

  • .. 你的预期行为是什么?
  • 例如,它应该用于像 Steam 这样的平台。你点击播放,它开始游戏。但是在这种情况下,您可能会发现自己处于想要第二次甚至第三次击球的情况。好吧,按照当时的代码方式,它会开始运行游戏的多个实例。但几乎没有修复它。

标签: javascript node.js electron child-process


【解决方案1】:

这段代码可能会被多次调用,而您在完成后忘记删除事件侦听器。我不知道如何解决它,但试试这个:

ipcMain.once("run_crystal", () => {
   [your code here]
});

或者:

ipcMain.on("run_crystal", () => {
   [your code here]
   ipcMain.removeAllListeners("run_crystal");
});

【讨论】:

  • 很高兴听到。老实说,我也曾为此挣扎过。
【解决方案2】:

目前,我使用了这个解决方案:

  ipcMain.on("run_crystal", () => {
      if(if_started == 0){
      if_started = 1;
      var cp = require("child_process");
      console.log("mesajul a ajuns");
      executablePath = crystal + "\\CrystalDM\\Server\\CrystalDMServer.exe";
      var Server_child = cp.spawn(executablePath);
      executablePath = crystal + "\\CrystalDM\\Game\\CrystalDM.exe";
      var parameters = ["test"];
      var options = {cwd:crystal+"\\CrystalDM\\Game"};
      var Game_child = cp.execFile(executablePath, parameters, options,
      (error, stdout, stderr) =>{
         Game_child.kill("SIGINT");
         Server_child.kill("SIGINT");
         delete Game_child;
         delete Server_child;
         delete cp;
         delete parameters;
         delete options;
         if_started = 0;
      });
    }
});

【讨论】:

    【解决方案3】:

    如果您不想多次启动一个进程,则必须跟踪已启动的进程。

     let runningProcesses = {};
    
     ipcMain.on("run_crystal", (event, arg) => {
       var cp = require("child_process");
       executablePath = crystal + "\\CrystalDM\\Server\\CrystalDMServer.exe";
    
       if (runningProcesses[executablePath]){ // boolean value for a single process or int if you want to allow multiple instances runningProcesses[executablePath] < maxProcessCounts
         event.sender.send('process-running', { process: executablePath })
       } else {
    
         runningProcesses[executablePath] = true; // boolean value for a single process or int if you want to allow multiple instances
    
         var Server_child = cp.spawn(executablePath);
    
         Server_child.on('close', (code, signal) => {
           runningProcesses[executablePath] = false; // or delete runningProcesses[executablePath]; 
         });
    
         event.sender.send('process-started', { process: executablePath })
    
         executablePath = crystal + "\\CrystalDM\\Game\\CrystalDM.exe";
         var parameters = ["test"];
         var options = {cwd:crystal+"\\CrystalDM\\Game"};
         console.log("a intrat in start game si urmeaza sa ruleze " + executablePath)
         var Game_child = cp.execFile(executablePath, parameters, options,(error, stdout, stderr) =>{
            console.log(stdout)
            Game_child.kill("SIGINT");
            Server_child.kill("SIGINT");
            delete Game_child;
            delete Server_child;
            delete cp;
        });
      }
    });
    

    【讨论】:

      猜你喜欢
      • 2020-08-10
      • 1970-01-01
      • 2022-12-20
      • 2019-04-04
      • 2018-12-17
      • 2014-01-24
      • 2011-11-12
      • 2018-07-15
      • 1970-01-01
      相关资源
      最近更新 更多