4

I'm developing an app in Electron and I need to handle a custom protocol inside this app.
I'm using app.setAsDefaultProtocolClient(PROTOCOL) for that.

I am using "open-url" for macOS to handle the URL with my custom protocol and it is working smoothly but I can't figure it out on Windows. I'm sending some data in the URL so just opening the window won't work.

I checked this answer, but this was answered in 2016 and the method makeSingleInstance is now deprecated. In the docs, it suggests to use requestSingleInstanceLock but it doesn't take any callbacks or return URL.

So how can I enable the same feature in both macOS and Windows?


Code

index.js

app.on('ready', () => createWindow(`file://${__dirname}/views/welcome.html`));

app.on('activate', () => {
  // eslint-disable-next-line no-shadow,global-require
  const { mainWindow } = require('./utils/createWindow');
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (mainWindow === null) {
    createWindow(`file://${__dirname}/views/welcome.html`);
  }
});

app.on('open-url', handleOpenURL);

app.setAsDefaultProtocolClient(PROTOCOL);

handleOpenURL.js

module.exports = (e, data) => {
  e.preventDefault();
  // Some other Logic
  createWindow(URL);
}
Apal Shah
  • 680
  • 8
  • 17
  • 2
    I think there is no tutorial available for windows to handle the same situation. You can register the protocol. and look for the process arguements to handle this. using process.argv . – Sharvin K Oct 30 '19 at 10:42
  • 2
    Also you can try this event for the same, https://github.com/electron/electron/blob/master/docs/api/app.md#event-second-instance – Sharvin K Oct 30 '19 at 10:46
  • I tried this example: https://electronjs.org/docs/all#apprequestsingleinstancelock. I tried printing `event, commandLine, workingDirectory`, but this event is never getting executed. – Apal Shah Oct 30 '19 at 11:08
  • ok then you can try using the process.argv to get the passed argements – Sharvin K Oct 30 '19 at 11:10
  • Not able to figure out which event can handle a newly opened window where I can use process.argv – Apal Shah Oct 30 '19 at 11:20
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/201598/discussion-between-sharvin-k-and-apal-shah). – Sharvin K Oct 30 '19 at 11:26

1 Answers1

8

Take a look at this example it is built with angular and electron.

You just need to make sure of the following for the custom uri to work on windows:

First, only one instant is running, by checking app.requestSingleInstanceLock() if it is true then you need to quit the app app.quit(). because we only need one instance to run. Second, you should handle the second-instance event app.on('second-instance', (event, args) => {})

const customSchemeName = 'x-company-app';
const primaryInstance = app.requestSingleInstanceLock();
if (!primaryInstance) {
        app.quit();
        return;
}

// The primary instance of the application will run this code, not the new  instance
app.on('second-instance', (event, args) => {
    // handle custom uri
}

...
// Register private URI scheme for the current user when running for the first time
app.setAsDefaultProtocolClient(customSchemeName);

// Handle custom uri requests against the running app on Mac OS
app.on('open-url', (event, customSchemeData) => {
    event.preventDefault();
    // handle the data
});
...

I had the same issue on windows, this fixed it for me, I have tested it and it works. credits goes to gary archer.

Waleedoo
  • 105
  • 9
  • 1
    The problem is, this event `second-instance` is not getting triggered. I tried adding logs and added the [`dialog`](https://electronjs.org/docs/api/dialog) in the production build but it is not working. – Apal Shah Nov 02 '19 at 07:59
  • 1
    @ApalShah (and future readers) I had the same issue with the event not being triggered. I got it fixed by starting from a bare-bone app (like the example from above) and verifying that it works. Copying that code into my actual app and commenting out everything else. Finally, start to uncomment things from your app and see when you stop seeing the `second-instance` event working. In my case, the problem was with the line `app.setPath('userData', path.join(app.getPath('appData'), name))`. For now, it's still commented out. – Timothée Boucher Nov 18 '22 at 10:54