基于 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)