基於 electron-builder
package.json
// fileAssociations 為文件關聯
// mac 環境需要在 extendInfo 中配置 CFBundleURLSchemes
"build": {
"fileAssociations": {
"ext": [
"txt"
],
"role": "Editor"
},
"mac": {
"extendInfo": {
"CFBundleURLSchemes": [
"protocol"
]
}
}
}
main.js
let openFromProtocolUrl = ''
const openUrl = (url) => {
mainWindow.isMinimized() && mainWindow.restore()
// 正則中的 protocol 為自己定義的偽協議
if (url.match(/^protocol\:\/\//)) {
mainWindow.webContents.send('open-url', decodeURIComponent(url))
} else {
mainWindow.webContents.send('open-file', url)
}
mainWindow.focus()
}
if (isWin) {
const argv = process.argv.slice()
openFromProtocolUrl = argv.pop() // 啟動參數的數組的最后一項是喚醒鏈接
}
// 省略代碼
function createWindow() {
mainWindow = new BrowserWindow({...})
// 從協議打開應用時,mainWindow 還沒有創建完成
setTimeout(() => {
if (openFromProtocolUrl) {
openUrl(openFromProtocolUrl)
openFromProtocolUrl = ''
}
}, 1500)
}
const openUrlListener = function (event, url) {
if (mainWindow) {
openUrl(url)
} else {
openFromProtocolUrl = url // 如果 mainWindow 還沒創建,就先緩存
}
}
app.on('open-url', openUrlListener)
app.on('open-file', openUrlListener)
app.setAsDefaultProtocolClient('protocol') // 設置偽協議
渲染進程
const fileAssociationsReg = /\.txt$/g
const fileOpened = async (path) => {
const match = path.match(fileAssociationsReg)
if (!match) return console.log(`%c錯誤,該文件不為文本:${path}`, 'color:red')
// 省略
}
ipcRenderer.on('open-file', fileOpened)
const urlListener = (event, url) => {
const payload = url.replace(/protocol\:\/\//, '').split('/')
// 省略
}
ipcRenderer.on('open-url', listener)