How to prevent multiple instances in Electron
Asked Answered
S

4

64

I do not know if this is possible but I might as well give it a chance and ask. I'm doing an Electron app and I'd like to know if it is possible to have no more than a single instance at a time.

I have found this gist but I'm not sure hot to use it. Can someone shed some light of share a better idea ?

var preventMultipleInstances = function(window) {
    var socket = (process.platform === 'win32') ? '\\\\.\\pipe\\myapp-sock' : path.join(os.tmpdir(), 'myapp.sock');
    net.connect({path: socket}, function () {
        var errorMessage = 'Another instance of ' + pjson.productName + ' is already running. Only one instance of the app can be open at a time.'
        dialog.showMessageBox(window, {'type': 'error', message: errorMessage, buttons: ['OK']}, function() {
            window.destroy()
        })
    }).on('error', function (err) {
        if (process.platform !== 'win32') {
            // try to unlink older socket if it exists, if it doesn't,
            // ignore ENOENT errors
            try {
                fs.unlinkSync(socket);
            } catch (e) {
                if (e.code !== 'ENOENT') {
                    throw e;
                }
            }
        }
        net.createServer(function (connection) {}).listen(socket);;
    });
}
Sind answered 10/3, 2016 at 12:11 Comment(2)
Would you mind changing the accepted answer, because the Electron API has changed and now recommends requestSingleInstanceLock instead of makeSingleInstanceHike
@Hike sorted :)Sind
C
146

There is a new API now: requestSingleInstanceLock

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, we should focus our window.
    if (myWindow) {
      if (myWindow.isMinimized()) myWindow.restore()
      myWindow.focus()
    }
  })
    
  // Create myWindow, load the rest of the app, etc...
  app.on('ready', () => {
  })
}

Clynes answered 3/10, 2018 at 18:35 Comment(5)
This is needed since electron 4.0Maurine
Keep in mind here that app.quit() doesn't terminate immediately, so if you have code afterwards it will still run.Coraleecoralie
What's the purpose of app.quit()? Why would I do it? Is it in case it failed to acquire the lock?Integration
@Integration Pretty much. If the instance fails to acquire the lock, it means that it's a duplicate instance which, in this case, we want to close. Then, because the first instance was listening to second-instance, the window of that first instance is focused.Calicle
This code works, but doesn't make sense since basically what is happening we are running both the if and else logic. To my understanding the newly opened app will go into the 1st if and then close the newly opnened app. Our instance that is already running will go into the else statement and restore and focus it. Is that correct?Birdsong
G
33

Use the makeSingleInstance function in the app module, there's even an example in the docs.

Gustation answered 10/3, 2016 at 16:5 Comment(2)
Wow, I feel dumb. I never seen that in their API. I was reading from here http://electron.atom.io/docs/v0.36.8/Sind
Release notes for Electron 4 say that makeSingleInstance is deprecated. Use requestSingleInstanceLock.Brobdingnagian
C
9

In Case you need the code.

let mainWindow = null;
//to make singleton instance
const isSecondInstance = app.makeSingleInstance((commandLine, workingDirectory) => {
    // Someone tried to run a second instance, we should focus our window.
    if (mainWindow) {
        if (mainWindow.isMinimized()) mainWindow.restore()
        mainWindow.focus()
    }
})

if (isSecondInstance) {
    app.quit()
}
Corporeal answered 15/1, 2018 at 6:3 Comment(0)
D
0

I only find one way to work electron 16, makesingleinstance is deprecated... use this:

  const additionalData = { myKey: 'myValue' };
  const gotTheLock = app.requestSingleInstanceLock(additionalData);

      if (!gotTheLock) {
        app.quit();
      } else {
        app.on(
        'second-instance',
        (event, commandLine, workingDirectory, additionalData) => {
          // Print out data received from the second instance.
          console.log(additionalData);
          // Someone tried to run a second instance, we should focus our window.
          if (mainWindow) {
            if (mainWindow.isMinimized()) mainWindow.restore();
            mainWindow.focus();
          }
        });
        app.whenReady().then(() => {
            createWindow();
        });
      }
Diapedesis answered 17/8, 2023 at 0:17 Comment(1)
And how is this different compared to the currently accepted answer?Sind

© 2022 - 2024 — McMap. All rights reserved.