How to open application from a url on both macOS and Windows?


#1

Hi,

I have created an app that works well on macOS but I’m having some issues with Windows. On macOS I’m using the app “open-url” event but I realised that it’s not available on Windows when I tested my app. Does anyone know how I can create something that works on both platforms?

The app should be able handle the event when its not already running and if its already running.

Here’s the code that I currently have:

const electron          = require('electron')
const app               = electron.app
const BrowserWindow     = electron.BrowserWindow
const Menu              = electron.Menu
const path              = require('path')
const urlUtilities      = require('url')
const windowStateKeeper = require('electron-window-state')
const menu              = require('./electron/ui/menu')
const {is}              = require('electron-util')

let win
let urlToOpenOnStartup = null

if (!app.requestSingleInstanceLock()) {
	app.quit()
}
else {
	app.on('second-instance', () => {
		if (win) {
			if (win.isMinimized()) {
				win.restore()
			}

			win.focus()
		}
	})

	app.setAsDefaultProtocolClient('foobar')

	app.on('open-url', (event, url) => {
		event.preventDefault()

		if (win) {
			win.webContents.send('open-url', url)
		}
		else {
			urlToOpenOnStartup = url
		}
	})

	const createWindow = () => {

		let windowState = windowStateKeeper({
			defaultWidth: 500,
			defaultHeight: 800
		})

		win = new BrowserWindow({
			titleBarStyle: is.macos ? 'hidden' : 'default',
			x: windowState.x,
			y: windowState.y,
			width: windowState.width,
			height: windowState.height,
			minHeight: 500,
			minWidth: 500,
			show: false
		})

		win.once('ready-to-show', () => {
			win.show()
		})

		windowState.manage(win)

		if (is.development) {
			win.loadURL('http://localhost:3000')

			win.webContents.openDevTools()
		}
		else {
			win.loadURL(urlUtilities.format({
				pathname: path.join(__dirname, '../build/index.html'),
				protocol: 'file:',
				slashes: true
			}))
		}

		win.on('closed', () => {
			win = null
		})
	}

	app.on('ready', () => {
		createWindow()

		Menu.setApplicationMenu(menu)

		if (urlToOpenOnStartup !== null) {
			win.once('show', () => {
				win.webContents.send('open-url', urlToOpenOnStartup)

				urlToOpenOnStartup = null
			})
		}
	})

	app.on('window-all-closed', () => {
		app.quit()
	})
	
	app.on('activate', () => {
		if (win === null) {
			createWindow()
		}
	})
}

#2

Looks like bugs are frequently submitted about setAsDefaultProtocolClient on windows: https://github.com/electron/electron/issues?utf8=✓&q=is%3Aissue+setAsDefaultProtocolClient+

The thing I would check first is, does it work if the application is launched with administrator privileges?


#3

setAsDefaultProtocolClient seems to be working fine but the problem is that the “open-url” is a macOS only feature.

I have been doing some extensive googling and it seems like I can use “argv” and the “second-instance” event to check for urls on windows. I’ll have to set up a windows dev environment to test this tomorrow.