Aller au contenu principal

Liens profonds

Vue d'ensemble

This guide will take you through the process of setting your Electron app as the default handler for a specific protocol.

À la fin de ce tutoriel, votre application sera configurée pour intercepter et gérer toutes les URL commençant par un protocole spécifique. Pour cet exemple, le protocole utilisé sera "electron-fiddle://".

Exemples

Processus principal (main.js)

Importons tout d'abord, depuis electron, les modules requis. Ces modules aident à gérer le cycle de notre application et à créer une fenêtre de navigateur native.

const { app, BrowserWindow, shell } = require('electron')
const path = require('node:path')

Ensuite, nous allons procéder à l’enregistrement de notre application comme gestionnaire de tous les protocoles "electron-fiddle://« .

if (process.defaultApp) {
if (process.argv.length >= 2) {
app.setAsDefaultProtocolClient('electron-fiddle', process.execPath, [path.resolve(process.argv[1])])
}
} else {
app.setAsDefaultProtocolClient('electron-fiddle')
}

Nous allons maintenant définir la fonction chargée de la création de notre fenêtre de navigateur et charger le fichier index.html de notre application.

let mainWindow

const createWindow = () => {
// Création de la BrowserWindow.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})

mainWindow.loadFile('index.html')
}

Dans l'étape suivante , nous allons créer notre BrowserWindow et dire à notre application comment gérer un événement venant d'un lien vers un protocole externe.

Ce code sera différent sur Windows et Linux par rapport à MacOS. Cela est dû au fait que les deux plateformes émettent l'événement second-instance plutôt que l'événement open-url et Windows nécessitant du code supplémentaire pour ouvrir le contenu du lien de protocole dans la même instance Electron. Read more about this here.

Code Windows et Linux :

const gotTheLock = app.requestSingleInstanceLock()

if (!gotTheLock) {
app.quit()
} else {
app.on('second-instance', (event, commandLine, workingDirectory) => {
// quelqu'un a essayé d'exécuter une deuxième instance, on doit donc donner le focus à la fenêtre.
if (mainWindow) {
if (mainWindow.isMinimized()) mainWindow.restore()
mainWindow.focus()
}
// la variable commandLine est un tableau de chaine de caractères dans lequel le dernier élément est l'url du lien profond
dialog.showErrorBox('Welcome Back', `You arrived from: ${commandLine.pop()}`)
})

// Création de mainWindows, chargement du reste de l'application, etc...
app.whenReady().then(() => {
createWindow()
})
}

Code MacOS :

// Cette méthode sera appelée quant Electron aura fini
// de s'initialiser et sera prêt à créer des fenêtres de navigation.
// Certaines APIs peuvent être utilisées uniquement quant cet événement est émit.
app.whenReady().then(() => {
createWindow()
})

// gestion du protocole. Dans ce cas, nous choisissons d’afficher une boîte d’erreur.
app.on('open-url', (event, url) => {
dialog.showErrorBox('Content de vous revoir ', `Vous venez de: ${url}`)
})

Enfin, nous ajouterons du code supplémentaire pour gérer la fermeture de notre application par l'utilisateur.

// Quitter lorsque toutes les fenêtres sont fermées, sauf sur macOS. Là, il est courant
// pour les applications et leur barre de menus de rester actives jusqu’à ce que l’utilisateur quitte
// explicitement avec Cmd + Q.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})

Notes importantes

Empaquetage

Sous macOS et Linux, cette fonctionnalité ne fonctionnera que si votre application est empaquetée. Cela ne fonctionne pas lorsque vous le lancez en développement à partir de la ligne de commande. Lorsque vous empaquetez votre application, vous devrez vous assurer que les fichiers Info.plist sur macOS ou .desktop sur Linux ont bien été mis à jour pour inclure le nouveau gestionnaire de protocole. Certains des outils d'Electron pour regrouper et distribuer des applications gèrent cela pour vous.

Electron Forge

If you're using Electron Forge, adjust packagerConfig for macOS support, and the configuration for the appropriate Linux makers for Linux support, in your Forge configuration (please note the following example only shows the bare minimum needed to add the configuration changes):

{
"config": {
"forge": {
"packagerConfig": {
"protocols": [
{
"name": "Electron Fiddle",
"schemes": ["electron-fiddle"]
}
]
},
"makers": [
{
"name": "@electron-forge/maker-deb",
"config": {
"mimeType": ["x-scheme-handler/electron-fiddle"]
}
}
]
}
}
}

Electron Packager

Prise en charge de macOS :

Si vous utilisez l'API d'Electron Packager, l'ajout du support des gestionnaires de protocoles s'effectue de la même manière qu'avec Electron Forge, excepté que protocols fait partie des options de Packager passées à la fonction packager.

const packager = require('@electron/packager')

packager({
// ...other options...
protocols: [
{
name: 'Electron Fiddle',
schemes: ['electron-fiddle']
}
]

}).then(paths => console.log(`SUCCESS: Created ${paths.join(', ')}`))
.catch(err => console.error(`ERROR: ${err.message}`))

Si vous utilisez le CLI d’Electron Packager, utilisez les indicateurs --protocol et --protocol-name . Par exemple :

npx electron-packager . --protocol=electron-fiddle --protocol-name="Electron Fiddle"

Conclusion

Après avoir démarré votre application Electron, vous pouvez entrer une URL dans votre navigateur qui contient le protocole personnalisé, comme par exemple "electron-fiddle://open" et observer que l’application répondra et affichera une boîte de dialogue d’erreur.

// Modules to control application life and create native browser window
const { app, BrowserWindow, ipcMain, shell, dialog } = require('electron/main')
const path = require('node:path')

let mainWindow

if (process.defaultApp) {
if (process.argv.length >= 2) {
app.setAsDefaultProtocolClient('electron-fiddle', process.execPath, [path.resolve(process.argv[1])])
}
} else {
app.setAsDefaultProtocolClient('electron-fiddle')
}

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 (mainWindow) {
if (mainWindow.isMinimized()) mainWindow.restore()
mainWindow.focus()
}

dialog.showErrorBox('Welcome Back', `You arrived from: ${commandLine.pop().slice(0, -1)}`)
})

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

app.on('open-url', (event, url) => {
dialog.showErrorBox('Welcome Back', `You arrived from: ${url}`)
})
}

function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})

mainWindow.loadFile('index.html')
}

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})

// Handle window controls via IPC
ipcMain.on('shell:open', () => {
const pageDirectory = __dirname.replace('app.asar', 'app.asar.unpacked')
const pagePath = path.join('file://', pageDirectory, 'index.html')
shell.openExternal(pagePath)
})