61

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);;
    });
}
Eduard
  • 3,395
  • 8
  • 37
  • 62

4 Answers4

136

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', () => {
  })
}

roeland
  • 6,058
  • 7
  • 50
  • 67
  • 2
    This is needed since electron 4.0 – HarlemSquirrel Mar 06 '19 at 21:58
  • 3
    Keep in mind here that app.quit() doesn't terminate immediately, so if you have code afterwards it will still run. – Amir Ebrahimi Dec 05 '20 at 02:46
  • What's the purpose of `app.quit()`? Why would I do it? Is it in case it failed to acquire the lock? – felipecrs Nov 28 '21 at 20:34
  • @felipecrs 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. – jivanf Dec 12 '22 at 08:03
32

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

Vadim Macagon
  • 14,463
  • 2
  • 52
  • 45
  • 1
    Wow, I feel dumb. I never seen that in their API. I was reading from here [http://electron.atom.io/docs/v0.36.8/](http://electron.atom.io/docs/v0.36.8/) – Eduard Mar 10 '16 at 18:21
  • 17
    Release notes for Electron 4 say that `makeSingleInstance` [is deprecated](https://github.com/electron/electron/blob/master/docs/api/breaking-changes.md#planned-breaking-api-changes-40). Use `requestSingleInstanceLock`. – jayarjo Apr 24 '19 at 05:16
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()
}
manish kumar
  • 4,412
  • 4
  • 34
  • 51
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();
        });
      }
toyota Supra
  • 3,181
  • 4
  • 15
  • 19