Search code examples
node.jsreactjselectronchild-process

How to kill specific child process in react-electron


My electron app consists of '2 hello' buttons and 2 'cancel' buttons. Each 'hello' button will triggered a child process which carry out same function and cancel button will kill the child process.

My problem is the function that triggered by the second "hello" button can be terminated by the first cancel button.

All I want is the first 'cancel' button will kill the first 'hello' button's child process only and so on.

Any suggestions and help will be appreciated. Thank you

My user interface: enter image description here

My code on electron:

let process = null

ipcMain.on("runScript", (event, data) => {
   process = spawn('node helloworld.js', [], { shell: 
    true })
  });

ipcMain.on("killScript", (event, data) => {
    console.log(process)
    kill(process.pid, 'SIGKILL')


});

on my client side:

<div>
  <button onClick={() => ipcRenderer.send('runScript')}>hello</button>
  <button onClick={() => ipcRenderer.send('killScript')}>cancel</button>
</div>

Solution

  • There's something that you need to note, since you're trying to spawn multiple processes, you need to either store them in an array rather than a variable or have 2 variables, one for each button/process spawned, because the process that was in the process variable before is being overwritten each time you click any of the two hello buttons, since they emit the same event and are going to be killed by either of the cancel buttons.

    If you're going to have the same number of buttons, i.e., just the two you've created, then do something like this:

    // Backend
    let process1, process2 = null
    
    ipcMain.on("runScript", (event, data) => {
       if(data.process == 1) process1 = spawn('node helloworld.js', [], { shell: 
        true });
       else if(data.process == 2) process2 = spawn('node helloworld.js', [], { shell: 
        true })
       
      });
    
    ipcMain.on("killScript", (event, data) => {
        if(data.process == 1) {
           kill(process1.pid, 'SIGKILL');
        } else if (data.process == 2) kill(process2.pid, 'SIGKILL');    
    });
    
    // Client side
    <div>
      <button onClick={() => ipcRenderer.send('runScript', {process: 1})}>hello</button>
      <button onClick={() => ipcRenderer.send('killScript', {process: 1})}>cancel</button>
    </div>
    <div>
      <button onClick={() => ipcRenderer.send('runScript', {process: 2})}>hello</button>
      <button onClick={() => ipcRenderer.send('killScript', {process: 2})}>cancel</button>
    </div>
    

    If you're going to have a variable number of buttons, you need to implement the same solution just with an array on the backend and the {process: processNumber} needs to also correspond to the correct process in the process array on the backend.