上一期我们介绍了如何设置伪协议,并通过伪协议链接拉起客户端,其实伪协议还有很多场景的,比如百度网盘或者迅雷,点击网页上的链接进行下载,或者点击链接拉起客户端后打开某个页面,其实这都是可以用伪协议链接实现的,链接中的参数就和网页的参数没啥区别,本期就介绍如何获取伪协议链接中的参数。
上一章我们介绍了伪协议是怎么启动客户端的,即:
%1
启动客户端的。info.plist
文件设置启动客户端的。这两者的启动方式不同,故获取方式也是不同的,我们来看一下通过伪协议的启动流程吧:
%1
),也就是我们实际上打开的是xxx.exe vue-cli-electron://xxxx
,process.argv
来获取这个伪协议链接,之前说了process.argv
这个是数组,里面是Electron的启动参数,如果我们是通过伪协议拉起软件的话,数组最后一项就是我们的伪协议链接process.argv:
[
xxx.exe,
.....,
vue-cli-electron://xxxx
]
那么此时伪协议为process.argv[process.argv.length - 1]
second-instance
事件来获取这个argv,second-instance
当第二个实例被执行并且调用app.requestSingleInstanceLock()
时触发的,解释一下就是我们的软件正在运行,伪协议触发打开exe,我们主进程中调用了app.requestSingleInstanceLock()
的话,second-instance
就会触发,直观表现为伪协议打开软件,触发second-instance
事件,我们可以在这个里面拿到argv。import { app } from 'electron'
import global from '../config/global'
const gotTheLock = app.requestSingleInstanceLock()
export default function() {
// 点击图标启动时检测窗口是否存在,存在则打开
if (!gotTheLock) {
app.quit()
} else {
app.on('second-instance', (event, argv) => {
console.log(argv[argv.length - 1])
const win = global.sharedObject.win
if (win) {
if (win.isMinimized()) win.restore()
if (win.isVisible()) {
win.focus()
} else {
win.show()
win.setSkipTaskbar(false)
}
}
})
}
}
Mac软件的启动就没啥参数可带的了,所以process.argv
这个东西没啥用,那么如何获取呢,看看官方描述链接:
在 macOS 上, 当用户尝试在 Finder 中打开您的应用程序的第二个实例时, 系统会通过发出 open-file 和 open-url 事件来自动强制执行单个实例,。 但是当用户在命令行中启动应用程序时, 系统的单实例机制将被绕过, 您必须手动调用此方法来确保单实例。
故我们可以通过open-url
来获取我们的伪协议链接,注:Mac系统无论软件启动或没启动都是通过open-url
来拿取的
app.on('open-url', (_event, urlStr) => {
console.log(urlStr)
})
import { app } from 'electron'
import global from '../config/global'
const gotTheLock = app.requestSingleInstanceLock()
export default function() {
// 点击图标启动时检测窗口是否存在,存在则打开
if (!gotTheLock) {
app.quit()
} else {
// 这里是软件在启动时,伪协议打开触发的
app.on('second-instance', (event, argv) => {
console.log(argv)
const win = global.sharedObject.win
// 直接把伪协议链接发送给渲染进程
win.webContents.send('renderer-scheme', argv[argv.length - 1])
if (win) {
if (win.isMinimized()) win.restore()
if (win.isVisible()) {
win.focus()
} else {
win.show()
win.setSkipTaskbar(false)
}
}
})
}
}
import winSingle from './services/winSingle'
winSingle()
app.isReady() ? onAppReady() : app.on('ready', onAppReady)
async function onAppReady() {
if (!process.env.WEBPACK_DEV_SERVER_URL) {
createProtocol('app')
}
// 这里怎么处理看个人喜好,你可以启动时就根据scheme打开对应的窗口,或者是在窗口加载完成后发个通知给渲染进程,渲染进程进行重定向。
// if (process.argv.length > (app.isPackaged ? 1 : 2)) {
// const scheme = process.argv[process.argv.length - 1]
// 处理scheme省略
// initWindow('#xxxpath')
// } else {
// initWindow('')
// }
initWindow('')
// 这里的逻辑是win关闭通过伪协议拉起软件,由于我们要通知渲染进程,所以得在渲染进程加载完毕后通知
win.webContents.once('did-finish-load', () => {
// 直接打开软件的话开发环境的启动参数为2,安装包为1,大于这个数的话说明是通过伪协议拉起软件的
if (process.argv.length > (app.isPackaged ? 1 : 2)) {
// 我们这里主动触发'second-instance',传入process.argv,在那边统一处理了
app.emit('second-instance', null, process.argv)
}
})
}
// mac伪协议链接就是urlStr
app.on('open-url', (_event, urlStr) => {
console.log(urlStr)
if (win) {
// 这里是mac软件打开时使用伪协议打开软件
win.webContents.send('renderer-scheme', urlStr)
if (win.isMinimized()) win.restore()
if (win.isVisible()) {
win.focus()
} else {
win.show()
win.setSkipTaskbar(false)
}
} else {
// 这里是mac软件关闭时使用伪协议打开软件,如果你中间process.argv没有改变可以这样写,会继续走上面win的did-finish-load的流程
// 如果有改变的话老老实实写个did-finish-load进行win.webContents.send('renderer-scheme', urlStr)推送
process.argv.push(urlStr)
}
})
我这里是主进程获取到伪协议链接,然后发通知给渲染进程的,一些不懂的地方请看上面注释解释,简单说一下就是:
open-url
里处理Mac的伪协议,根据win的值来区分软件是处于开启还是关闭。ready
里拿到伪协议的是软件处于关闭状态的,second-instance
里软件是启动状态。这里我们使用的伪协议链接为vue-cli-electron:///file/localFile?image=https://xuxinblog.oss-cn-qingdao.aliyuncs.com/blog/2021/07/01/1.jpg
,拿到的也是这个完整链接,我们处理一下这个链接,跳转到/file/localFile
,并下载query参数里面的image图片地址。下载及显示逻辑用之前的加载本地文件的逻辑。
onMounted(() => {
window.ipcRenderer.on('renderer-scheme', (_event, data) => {
console.log(data)
const urlObj = new URL(data)
const query = {}
urlObj.search.slice(1).split('&').forEach(s => {
const item = s.split('=')
query[item[0]] = item[1]
})
router.replace({
path: urlObj.pathname.slice(2),
query
})
})
})
onUnmounted(() => {
window.ipcRenderer.removeAllListeners('renderer-scheme')
})
onMounted(() => {
const localImage = LgetItem('localImage')
if (route.query.image) {
download(route.query.image)
} else {
if (localImage) {
state.image = localImage
}
}
})
好了,接下来使用浏览器打开vue-cli-electron:///file/localFile?image=https://xuxinblog.oss-cn-qingdao.aliyuncs.com/blog/2021/07/01/1.jpg
试试,看看拉起软件后是否跳转到本地文件的路由,且显示的是伪协议中image的图片。
本系列更新只有利用周末和下班时间整理,比较多的内容的话更新会比较慢,希望能对你有所帮助,请多多star或点赞收藏支持一下
本文地址:https://xuxin123.com/electron/url-scheme-query
本文github地址:链接
content属性一般用于::before、::after伪元素中,用于呈现伪元素的内容。平时con...
Redis 官方在 2020 年 5 月正式推出 6.0 版本,提供很多振奋人心的新特性,所以...
先点赞再看,养成好习惯 前言 这两天在另一个社区看到了一个关于 Tomcat 的提问...
简介: 企业上云多账号架构中,如何做到从上到下管理的同时,处理好员工的权限边...
解决方法如下: 第一种 使用iframe,但是目前使用iframe的人已经越来越少了,而...
1.HTML5的内容类型 内容类型 描述 内嵌 向文档中添加其他类型的内容,例如audio...
data URI scheme 允许我们使用内联(inline-code)的方式在网页中包含数据,可以...
John Au-Yeung 来源:medium 译者:前端小智 有梦想,有干货,微信搜索 【大迁世...
注释1:上图整个大背景是这个网页的全部尺寸,中间的小框才是浏览器中的可见尺寸...
复制代码 代码如下: !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional...