pc网页端调起客户端应用的那些事--electron

2023-12-19 21:20

本文主要是介绍pc网页端调起客户端应用的那些事--electron,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Date: 2020.04.11

前言

 在当下大前端的趋势之下,我还是跟随大流跳入了electron 开发的坑。不过这个也让我不再局限于网页业务的开发,并对大前端所代表的的内容有了新的认识。如果是在去年听到大前端这个词,我也只是只知其名不懂其义。

 为了开发客户端的新业务,这三个月我接触了很多新知识,从基本的业务开发,electron 的构建配置和打包,针对 mac 应用的签名,公证和盖章, pc 客户端的ota升级,再到 jenkins 自动化构建配置,CI集成,再到现在的pc网页端调起客户端应用等业务。这些内容提高了还是前端切图仔的我的眼界【捂脸.jpeg】

 不过,这个三个月一直忙于业务开发,学到了很多内容,一直没有进行过总结,这个让我觉得很害怕,害怕学到的新知识会被忘掉,因此,今天还是赶紧针对这些知识点做一下部分总结。今天先整理一下pc网页端调起客户端应用的知识点。

正文

背景:今天要讨论的是在网页端打开客户端页面的功能,也许大家比较少接触过在 pc 端调起 pc 客户端的应用的功能;但是在移动端网页调起手机应用的操作,大家或多或少有接触过;其实无论在 pc 还是网页;它们实现调起客户端的原理都是类似的。接下来我会分享一下 pc 网端调起 eletron 客户端的那些事。

part 1: 如何在浏览器调起基于electron 开发的应用(原理)

  1. 基于自定义的伪协议(URL Scheme 协议),实现应用的调起
  2. URL Scheme 协议【理解为用于实现在浏览器跳转应用的协议就可以啦】
mac

配置 URL Schemes,往info.plist文件里配置好scheme。

Mac os上浏览器启动本地app主要是通过注册 URL Schemes,每个打包好的app文件中都会存在一个info.plist文件;

mac 用户可以尝试在配置了URL Schemes的应用中,查看已经安装好的应用的 URL Schemes 配置,步骤如下:

  1. 在应用程序中,找到对应的应用
  2. 右键显示包内容
  3. 打开 contents 文件
  4. 点击查看 Info.plist 找到 URL types – URL Schemes;
  5. 再通过浏览器打开输入该协议即可实现在浏览器调起应用。

以 xcode 为例:
6. 打开 xcode 的 Info.plist 文件。可看到其中一个 URL Schemes 为 xcode.
在这里插入图片描述
7. 再打开浏览器,在地址栏输入xcode://,即可调起 xcode 应用。
在这里插入图片描述
在这里插入图片描述

window

window 的调起类似;

只不过不是往info.plist文件里配置scheme,而是通过往注册表的 HKCR (HKEY_CALSSES_ROOT) 目录下添加一条记录来完成该协议的注册。

示例:在注册表的HKEY_CALSSES_ROOT目录下,添加一个xcode 字段,并将值指向 xcode 的 exe 包的路径;即可实现如上面 mac 的方式在浏览器调起应用。

暂时没有window 电脑在身边,使用了网上一张图作为例子,侵删
在这里插入图片描述

part 2: 那么如何在开发应用的时候定义好协议呢(怎么做)

其实关于 electron 应用协议的注册,electron 已经有提供相应的 api 啦 (app.setAsDefaultProtocolClient),我们可以直接使用。在进行 app 的相关事件监听和处理时,同时进行协议的注册。

// 示例1:比如说想通过在浏览器输入 “协议://”,就可以实现调起该应用,则实现如下
app.setAsDefaultProtocolClient("你的协议");// 示例2:比如说想通过在浏览器输入 “xcode://”,按照下面进行协议的注册,就可以实现调起该应用
app.setAsDefaultProtocolClient("xcode");

另外,还需要在 package.json 的 build 字段中的 protocols 对象进行 schemes 配置。

在mac中,该配置字段主要是用在将 schemes的值打包进 Info.plist 文件的URL Schemes。【如果没有进行这个配置,在第一次安装应用但未启动,直接通过网页端调起该应用,好像是无效的,除非已手动打开过一次该应用,主要是因为app.setAsDefaultProtocolClient(“你的协议”)这个操作是写在主进程里面,需要执行一遍应用的逻辑,即启动过应用,才能完成该协议的注册】。

window 只需要使用 app.setAsDefaultProtocolClient 在注册表进行注册即可。

  • 查看协议是否设置成功
  1. 分别进行mac 和window的打包
  2. mac 查看包的 Info.plist (URL types – URL Schemes)
  3. window 查看注册表
  • 调用方式

可以尝试在浏览器直接打开 注册的协议://,就可以完成浏览器的调起

part 3: 调起应用时触发的钩子函数

  1. mac 通过 app.on(‘open-url’, fun)监听
  2. window 通过 app.on(“second-instance”,fun)监听

mac 和 window有区别,开发和生产有区别

macOS 下通过URL Schemes协议调起应用时

主实例会通过 open-url 事件监听应用被调起的事件

// 网页进行应用的调起后,会触发该事件
app.on('open-url', (event, urlStr) => {console.log("mac 准备执行网页端调起客户端逻辑");handleUrlFromWeb(urlStr); // 对 url 执行的处理逻辑_handleBeforeOpenWindowByWeb(); // 利用相应的参数,打开其他页面(这个是我这边的需求用到),代码略
});
  • macOS中,打开协议的参数的处理
// 进行处理网页传来 url 参数,参数自定义,以下为示例
// 示例调起应用的 url 为(应用URL Schemes为youapp):youapp:?name=名字&type=类型&shareId=1585876954860136091
const handleUrlFromWeb = (urlStr) => {const urlObj = new URL(urlStr);const { searchParams } = urlObj;const shareId = searchParams.get('shareId');const name = searchParams.get('name');const type = searchParams.get('type');/** code这部分代码为使用这些参数执行相应的逻辑*/
};
window 下通过URL Schemes协议调起应用时

分两种情况

  1. 应用处于打开状态,会触发 second-instance 事件并接收这个 URL。

  2. 应用处于未打开状态,在网页端通过浏览器调起应用之后不会触发 second-instance 事件;这个时候需要主动判断应用是否是从网页端调起,并主动触发 second-instance 事件;

在 window 里面判断是否是从网页端的标准:如果是通过url schema启动,其启动参数会超过1个

以下为在应用 ready 之后,判断是否是在 window 下主动调起客户端,并主动触发 second-instance 事件的实现逻辑;

/*** 添加对协议链接的处理, 用于实现网页调起客户端逻辑*/
// 当应用启动完成后,主动判断应用是否是从网页中调起
const _handleAfterReady = () => {// windows如果是通过url schema启动则发出时间处理// 启动参数超过1个才可能是通过url schema启动if (process.argv.length > 1) {if (!app.isReady()) {app.once("browser-window-created", () => {// app 未打开时,通过 open-url打开 app,此时可能还没 ready,需要延迟发送事件// 此段ready延迟无法触发 service/app/ open-url 处理,因为saga初始化需要时间app.emit("second-instance", null, process.argv);});} else {app.emit("second-instance", null, process.argv);}}
};

触发 second-instance 事件之后的具体逻辑与 mac 类似,不过针对获取到的参数的处理方式还是存在一些差异

app.on('second-instance', async (event, argv) => {// Windows 下通过协议URL启动时,URL会作为参数,所以需要在这个事件里处理if (process.platform === 'win32') {console.log("window 准备执行网页端调起客户端逻辑");handleArgvFromWeb(argv);_handleOpenWindowByWeb();}
});

处理window下的参数

const PROTOCOL = '注册的协议名'; // 用户自定义// window 系统中执行网页调起应用时,处理协议传入的参数
const handleArgvFromWeb = (argv) => {const prefix = `${PROTOCOL}:`;// 开发阶段,跳过前两个参数(`electron.exe .`)// 打包后,跳过第一个参数(`myapp.exe`)const offset = app.isPackaged ? 1 : 2;const url = argv.find((arg, i) => i >= offset && arg.startsWith(prefix));if (url) handleUrlFromWeb(url);
};

补充: 从网页调起客户端时,在macos 中,既会触发 open-url 事件,也会触发 second-instance 事件;所以在写 second-instance事件 处理逻辑时,需要将 mac 排除掉,避免重复处理(通过判断 process.platform === ‘win32’【我们的应用只有Mac和window】)

part 4: 将被调起应用的可能存在的状态

这个部分主要是针对本人当下所做的需求去进行分析: 调起应用,根据是否登录,再决定是否打开新窗口并执行相应的业务逻辑(可以打开多个窗口)。按需浏览,业务不同可以考虑跳过该part,直接看下一部分。

  1. 已打开,已登录

这个时候,直接在浏览器通过协议打开即可

  1. 已打开,未登录

浏览器通过协议打开,显示登录窗口,登录成功,显示主窗口个,并打开对应功能窗口(要注意多窗口的处理,用户有可能在多个网页中调起了应用)

  1. 未打开,已登录 和 未打开,未登录
    如果只是使用 app.setAsDefaultProtocolClient(“你的协议”)进行 scheme 协议的注册;那么刚安装完应用,首次需要用户主动打开应用,才能完成 scheme 协议的注册;

如果想要在应用刚安装完成,不要求用户首次主动打开应用,也支持scheme 协议(通过网页调起)调起应用,则需要做一下配置

  • mac 应用,在package.json 的 build 字段中的 protocols 对象进行 schemes 配置即可。打包完成后,会在应用的 info.plist 看到相应的协议配置

  • window 应用,在需要通过在 package.json 中的 nsis 字段中配置相应的安装或卸载相关的脚本路径;配置应用在安装时,主动往注册表写入协议;
    在这里插入图片描述

  • 浏览器判断 scheme 协议是否存在(判断本地是否有安装应用,没安装跳下载地址)

part 5: 关于卸载的那些事

mac 卸载存在的坑:暂时没有发现

macOS 相关的卸载会比较简单,只在卸载应用即可完成卸载

window 卸载存在的坑:electron 开发的应用已完成卸载,但在注册表通过app.setAsDefaultProtocolClient 注册的协议没有删除
问题

但是针对 window 的应用的卸载后会有坑,直接通过 app.setAsDefaultProtocolClient(“你的协议”)可以完成协议的写入,但是应用却不会在卸载时主动删除注册表的协议;

这个时候就会存在一个坑,用户在浏览器再输入相应协议进行应用的调起时,浏览器依旧会弹出相应的提示弹窗(这个图是在mac 截的,window类似),点击打开应用,弹窗会被收起,但实际上并不会打开应用,因为应用已经被卸载,只是注册表的记录没被删除,导致依旧会出现弹窗。
在这里插入图片描述
这种情况其实并不会影响正常功能的使用了,但是测试人员说这个不是很美观。好吧,不美观,就再处理一下。

解决

这种情况应该就应用卸载的逻辑做一下配置才行。还记得上一下小部分,有说过可以通过 nsis 去进行应用的安装和卸载的相关配置(在我们应用中,window打包使用的是 electron-builder);

在 electron-builder 的说明文档中 nsis 模块的部分,有提供8个配置入口(customHeader, preInit, customInit, customUnInit, customInstall, customUnInstall, customRemoveFiles, customInstallMode),我将它们理解为插槽,用于针对安装和卸载去进行定制化配置

使用示例如下:

!macro customHeader!system "echo '' > ${BUILD_RESOURCES_DIR}/customHeader"
!macroend!macro preInit; This macro is inserted at the beginning of the NSIS .OnInit callback!system "echo '' > ${BUILD_RESOURCES_DIR}/preInit"
!macroend!macro customInit!system "echo '' > ${BUILD_RESOURCES_DIR}/customInit"
!macroend!macro customInstall!system "echo '' > ${BUILD_RESOURCES_DIR}/customInstall"
!macroend!macro customInstallMode# set $isForceMachineInstall or $isForceCurrentInstall # to enforce one or the other modes.
!macroend

我们的需求是在应用卸载时主动删除注册表的相关的协议,所以 installer.nsh 逻辑如下:

!macro customUnInstallDeleteRegKey HKCR "你注册的协议"
!macroend 

以上即在应用卸载时完成协议的删除

其他补充
  • HKCR 表示的 HKEY_CLASSES_ROOT 的在注册表的简写 [即注册表的路径]

  • nsis钩子详细说明:https://www.electron.build/configuration/nsis
    在这里插入图片描述

  • 参考写法(卸载程序):https://stackoom.com/question/3C5eL/nsis%E5%8D%B8%E8%BD%BD%E7%A8%8B%E5%BA%8F%E6%9C%AA%E5%88%A0%E9%99%A4%E7%94%B5%E5%AD%90%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%E7%9A%84%E6%B3%A8%E5%86%8C%E8%A1%A8-nsh%E8%84%9A%E6%9C%AC

这篇关于pc网页端调起客户端应用的那些事--electron的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/513747

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

zoj3820(树的直径的应用)

题意:在一颗树上找两个点,使得所有点到选择与其更近的一个点的距离的最大值最小。 思路:如果是选择一个点的话,那么点就是直径的中点。现在考虑两个点的情况,先求树的直径,再把直径最中间的边去掉,再求剩下的两个子树中直径的中点。 代码如下: #include <stdio.h>#include <string.h>#include <algorithm>#include <map>#

【区块链 + 人才服务】可信教育区块链治理系统 | FISCO BCOS应用案例

伴随着区块链技术的不断完善,其在教育信息化中的应用也在持续发展。利用区块链数据共识、不可篡改的特性, 将与教育相关的数据要素在区块链上进行存证确权,在确保数据可信的前提下,促进教育的公平、透明、开放,为教育教学质量提升赋能,实现教育数据的安全共享、高等教育体系的智慧治理。 可信教育区块链治理系统的顶层治理架构由教育部、高校、企业、学生等多方角色共同参与建设、维护,支撑教育资源共享、教学质量评估、

AI行业应用(不定期更新)

ChatPDF 可以让你上传一个 PDF 文件,然后针对这个 PDF 进行小结和提问。你可以把各种各样你要研究的分析报告交给它,快速获取到想要知道的信息。https://www.chatpdf.com/

【区块链 + 人才服务】区块链集成开发平台 | FISCO BCOS应用案例

随着区块链技术的快速发展,越来越多的企业开始将其应用于实际业务中。然而,区块链技术的专业性使得其集成开发成为一项挑战。针对此,广东中创智慧科技有限公司基于国产开源联盟链 FISCO BCOS 推出了区块链集成开发平台。该平台基于区块链技术,提供一套全面的区块链开发工具和开发环境,支持开发者快速开发和部署区块链应用。此外,该平台还可以提供一套全面的区块链开发教程和文档,帮助开发者快速上手区块链开发。

【C++高阶】C++类型转换全攻略:深入理解并高效应用

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C++ “ 登神长阶 ” 🤡往期回顾🤡:C++ 智能指针 🌹🌹期待您的关注 🌹🌹 ❀C++的类型转换 📒1. C语言中的类型转换📚2. C++强制类型转换⛰️static_cast🌞reinterpret_cast⭐const_cast🍁dynamic_cast 📜3. C++强制类型转换的原因📝