Wali Waqar
Wali Waqar

Reputation: 385

nodeJS - Communicate with an electron app running in the background through a CLI

as an example of what I'm trying to achieve, consider launching VS Code from the terminal. The code <file-name> command opens an instance of vs code if not only running, or tells it to open a file otherwise. Also, once opened, the user can use the terminal session for other tasks again (as if the process was disowned).

My script needs to interact with my electron app in the same way, with the only difference being that my app will be in the tray and not visible in the dock. . The solution only needs to work on linux

Upvotes: 7

Views: 1664

Answers (2)

Vlad Havriuk
Vlad Havriuk

Reputation: 1451

If I understand correctly, you want to keep only one instance of your app and to handle attempts to launch another instance. In old versions of Electron, app.makeSingleInstance(callback) was used to achieve this. As for Electron ...v13 - v15, app.requestSingleInstanceLock() with second-instance event is used. Here is an example how to use it:

const { app } = require('electron');
let myWindow = null;

const gotTheLock = app.requestSingleInstanceLock();

if (!gotTheLock) {
    app.quit();
} else {
    app.on('second-instance', (event, commandLine, workingDirectory) => {
        // Someone tried to run a second instance
        // Do the stuff, for example, focus the window
        if (myWindow) {
            if (myWindow.isMinimized()) myWindow.restore()
            myWindow.focus()
        }
    })

    // Create myWindow, load the rest of the app, etc...
    app.whenReady().then(() => {
        myWindow = createWindow();
    })
}

So when someone will launch ./app arg1 arg2 at the second time, the callback will be called. By the way, this solution is cross-platform.

Upvotes: 2

leitning
leitning

Reputation: 1506

Use a unix socket server for inter-process-communication.

In electron

const handleIpc = (conn) => {
  conn.setEncoding('utf8');
  conn.on('data',(line) => {
    let args = line.split(' ');
    switch(args[0]) {
      case 'hey': 
        conn.write('whatsup\n');
        break;
      default: conn.write('new phone who this?\n');
    }
    conn.end();
  })
}
const server = net.createServer(handleIpc);
server.listen('/tmp/my-app.sock');

Then your CLI is:

#!/usr/bin/node
const net = require('net');
let args = process.argv;
args.shift(); // Drop /usr/bin/node 
args.shift(); // Drop script path

let line = args.join(' ');
net.connect('/tmp/my-app.sock',(conn)=>{
  conn.setEncoding('utf8');
  conn.on('data',(response)=>{
    console.log(response);
    process.exit(0);
  });
  conn.write(line+'\n');
}).on('error',(err)=>{
  console.error(err);
  process.exit(1);
});

Upvotes: 4

Related Questions