Web 网页如何唤起本地 Windows 应用并传递参数(含 Electron 自动注册 + 手动配置指南)

Web 网页如何唤起本地 Windows 应用并传递参数(含 Electron 自动注册 + 手动配置指南)

本文基博客 《点击页面按钮唤醒桌面的应用 windows》 扩展整理

在现代企业级系统中,Web 应用常常需要与本地桌面程序协作。例如:

  • 点击网页上的“打印”按钮,自动调用专用打印软件;
  • 在 OA 系统中点击“打开合同”,直接唤起 PDF 阅读器或电子签章工具;
  • 第三方 SaaS 平台集成客户已有的 Windows 软件,实现数据互通。

你有没有注意到:飞书、钉钉、百度网盘、腾讯会议等软件,都能通过网页一键唤起本地客户端?

✅ 比如:飞书:lark://open/message?...钉钉:dingtalk://action=call&user=xxx百度网盘:baidunetdisk://download?file=...

这些能力背后,依赖的是 Windows 的 自定义 URL 协议(Custom URL Scheme) 机制。

Windows 的 自定义 URL 协议(Custom URL Scheme) 是一种系统级机制,允许开发者注册一个以 xxx:// 开头的协议(如 myapp://),并将其关联到本地某个可执行程序。

当用户在浏览器、资源管理器或其他支持 URL 调用的地方点击或访问该协议链接时,Windows 会自动启动对应的应用程序,并将完整的 URL 作为命令行参数传递给它。

本文将从零开始,教你如何:

  1. 手动注册自定义协议(适合测试或非 Electron 场景);
  2. 让 Electron 应用在安装时自动注册协议(开箱即用);
  3. 网页如何安全传参,本地程序如何接收;
  4. 解答一个关键问题:应用在后台运行和完全未启动,行为有何不同?

一、真实案例:主流软件如何做到“网页唤起本地应用”?

当你在浏览器点击飞书会议链接 lark://meet/12345,系统会立即启动飞书客户端并加入会议。这是因为在你首次安装飞书时,它就悄悄做了以下事情:

  • 在 Windows 注册表中注册了 lark 协议;
  • 将该协议绑定到 Feishu.exe 的安装路径;
  • 声明:“今后所有 lark:// 开头的请求,请交给我处理”。

类似地:

软件协议示例用途
钉钉dingtalk://发消息、拨号、打开工作台
百度网盘baidunetdisk://下载文件、打开本地目录
腾讯会议zoommtg:// / wemeet://加入会议
微信(Windows)weixin://打开聊天(部分版本支持)
💡 这些软件无需用户手动配置,安装即生效——这正是我们要实现的目标。

二、方案选择:手动注册 vs 自动注册

方式适用场景是否需要用户操作
手动修改注册表测试、内部工具、非打包应用✅ 需要
Electron 安装自动注册正式产品、分发给客户❌ 无需

下面分别介绍两种方式。


三、方式一:手动配置注册表(详细步骤)

📌 适用于:C++/C#/Python 打包的 exe、临时测试、无安装包的场景

步骤 1:确定你的应用路径

假设你的程序位于:
C:\MyApp\MyApp.exe

步骤 2:打开注册表编辑器

  • Win + R,输入 regedit,回车。

步骤 3:创建协议项

  1. 导航到 HKEY_CLASSES_ROOT
  2. 右键 → 新建 → 项,命名为你的协议名(如 myapp
  3. myapp 项内:
    • 右键 → 新建 → 字符串值,名称为 URL Protocol(值留空)
    • 双击左侧 (默认),设置值为 "URL: MyApp Protocol"(可选描述)

步骤 4:绑定到应用程序

继续在 myapp 下创建层级:

myapp └── shell └── open └── command 

进入 command,双击 (默认),输入:

"C:\MyApp\MyApp.exe" "%1" 
⚠️ 注意:路径必须用英文双引号包裹;%1 表示完整的 URL(如 myapp://action?file=xxx

步骤 5:验证是否成功

  • Win + R,输入 myapp://test
  • 如果你的程序启动,说明注册成功!

替代方法:使用 .reg 文件一键导入

新建 register_myapp.reg,内容如下:

Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\myapp] @="URL: MyApp Protocol" "URL Protocol"="" [HKEY_CLASSES_ROOT\myapp\shell\open\command] @="\"C:\\MyApp\\MyApp.exe\" \"%1\"" 

双击运行即可写入注册表。


四、方式二:Electron 应用安装时自动注册协议(推荐)

使用 electron-builder 打包时,只需简单配置,安装程序会自动完成注册。

步骤 1:在 package.json 中声明协议

{"name":"myapp","build":{"appId":"com.example.myapp","productName":"MyApp","win":{"target":"nsis"},"protocols":[{"name":"MyApp Protocol","schemes":["myapp"]}]}}

步骤 2:主进程监听协议唤起

// main.jsconst{ app }=require('electron'); app.on('open-url',(event, url)=>{ event.preventDefault();handleProtocol(url);});// Windows 启动时从 argv 获取if(process.defaultApp){const url = process.argv.find(arg=> arg.startsWith('myapp://'));if(url)handleProtocol(url);}functionhandleProtocol(fullUrl){ console.log('收到:', fullUrl);// 解析参数并处理业务逻辑}

步骤 3:构建安装包

npx electron-builder --win 

生成的 Setup.exe 在安装时会自动注册 myapp:// 协议,用户无需任何操作。


五、Web 页面如何唤起应用?(Vue2 示例)

<template> <button @click="launchApp">打开本地应用</button> </template> <script> export default { methods: { launchApp() { const params = new URLSearchParams({ action: 'print', filePath: 'C:\\Reports\\Q4.pdf' }); const url = `myapp://handle?${params.toString()}`; // myapp://handle?action=print&filePath=C%3A%5CReports%5CQ4.pdf window.location.href = url; } } } </script> 
🔔 浏览器可能会弹出安全提示:“是否允许打开 MyApp?”——这是正常现象。

六、关键问题:应用在后台运行 vs 完全未启动,有区别吗?

有!而且行为完全不同。

场景系统行为Electron 如何处理
应用未启动Windows 会启动新进程,并将 URL 作为命令行参数传入(process.argv[1]app.whenReady() 中解析 argv
应用已在后台运行Windows 会向已有进程发送 WM_COPYDATA 或触发 second-instance 事件监听 app.on('second-instance', ...)

Electron 推荐写法(兼容两种情况):

const gotTheLock = app.requestSingleInstanceLock();if(!gotTheLock){ app.quit();}else{ app.on('second-instance',(event, argv)=>{const url = argv.find(a=> a.startsWith('myapp://'));if(url)handleProtocol(url);}); app.whenReady().then(()=>{createWindow();// 首次启动检查const url = process.argv.find(a=> a.startsWith('myapp://'));if(url)handleProtocol(url);});}
✅ 这样无论应用是否已运行,都能正确接收参数。

七、重要提醒:Web 无法知道本地应用是否已安装或运行!

这是一个常见误区:

❌ “网页能否检测用户是否安装了 MyApp?”

答案:不能。
出于安全限制,浏览器无法探测本地文件系统或进程列表。你只能:

  • 尝试唤起协议;
  • 如果失败(如弹出“找不到应用”错误),引导用户去下载安装;
  • 或通过其他间接方式(如本地 HTTP 服务、WebSocket 心跳)判断,但这需要额外开发。

因此,良好的用户体验应包含 fallback 机制

functionlaunchApp(){const url ='myapp://test'; window.location.href = url;// 3 秒后若未跳转,说明可能未安装setTimeout(()=>{if(!document.hidden){alert('未检测到 MyApp,请先安装'); window.open('https://example.com/download');}},3000);}

八、总结

能力实现方式
✅ 网页唤起本地应用自定义 URL 协议(myapp://
✅ 安装时自动注册electron-builder + protocols 配置
✅ 手动注册(测试用)修改 HKEY_CLASSES_ROOT\myapp
✅ 传参与接收URL 查询参数 + Electron argv / open-url
✅ 兼容后台/未启动使用 requestSingleInstanceLock + second-instance
❌ 检测是否安装浏览器无法实现,需 fallback 引导

通过本文方法,你可以像飞书、钉钉一样,打造“网页一键唤起本地应用”的无缝体验。

🎯 适用场景:政企系统集成、医疗设备控制、金融终端、离线任务调度等。

现在,轮到你的应用登场了!🚀

Read more

【XR技术介绍】一文理清 OpenVR、OpenXR、SteamVR 与各厂商 SDK等容易混淆的概念

【XR技术介绍】一文理清 OpenVR、OpenXR、SteamVR 与各厂商 SDK等容易混淆的概念

在虚拟现实、混合现实开发领域,OpenVR、OpenXR、SteamVR 以及各硬件厂商专属 SDK,是我们经常遇到的东西。是不是傻傻分不清楚,容易混淆它们的定位、归属、功能与适用场景,这些到底是标准协议?还是插件?还是开发工具包?本文将从概念定义、制定 / 开发主体、核心职能、技术关系、适用场景多个维度,系统拆解它们差异与关联,帮你建立完整的认知框架。 一、基础概念总览:先分清 “标准” 与 “实现” 在正式拆解前,先建立一个核心认知:OpenXR 与 OpenVR 是行业标准 / 接口规范,属于抽象的技术协议;SteamVR 是基于标准的 runtime 运行时实现,是可落地的软件平台;硬件厂商 SDK 则是设备专属的底层驱动与开发工具包,是硬件直连的桥梁。标准解决 “兼容统一” 问题,运行时与

NotoSansSC-Regular.otf介绍与下载

总体概述 NotoSansSC-Regular.otf 是 “思源黑体” 家族中用于简体中文的常规字重(Regular)的 OpenType 字体文件。它是由 Adobe 与 Google 合作领导开发的一款开源字体,旨在作为一款“全能型”字体,满足各种场景下的中文显示需求。 核心特点详解 1. 名称含义 * Noto: 名称源于“No Tofu”(没有豆腐)。其目标是消除在计算机上因缺少对应字体而显示的空白方块(俗称“豆腐块”☐),实现“无豆腐”的全球文字支持。 * SansSC: “Sans” 表示无衬线体,“SC” 代表“简体中文”。所以 NotoSansSC 就是“用于简体中文的无衬线字体”。 * Regular: 指字体的字重为“常规”或“正常”,不是细体(Light)

Flutter 三方库 eip55 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、严谨、符合 Web3 标准的以太坊地址校验与防串改引擎

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 eip55 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、严谨、符合 Web3 标准的以太坊地址校验与防串改引擎 在鸿蒙(OpenHarmony)系统的区块链钱包应用、数字资产管理工具(如鸿蒙版 NFT 浏览器)或需要处理加密货币转账的场景中,如何确保用户输入的以太坊(Ethereum)地址既符合基本格式,又通过了大小写混合的校验和(Checksum)验证,防止因为单个字符手误导致的资产永久丢失?eip55 为开发者提供了一套工业级的、基于 EIP-55 提案的地址转换与验证方案。本文将深入实战其在鸿蒙 Web3 安全基座中的应用。 前言 什么是 EIP-55?它是由以太坊创始人 Vitalik Buterin 提出的地址校验和提案。通过在地址字符串中引入特定的。大小写混合模式(基于 Keccak-256 哈希)

基于FPGA的CARRY4 抽头延迟链TDC延时仿真

基于FPGA的CARRY4 抽头延迟链TDC延时仿真

基于FPGA的CARRY4 抽头延迟链TDC延时仿真 1 摘要 基于 FPGA 的 CARRY4 抽头延迟链 TDC,核心是利用 Xilinx FPGA 中 CARRY4 进位单元的固定、低抖动级联延迟构建抽头延迟线,通过锁存信号传播位置实现亚纳秒级时间测量,单级进位延迟约 10–30 ps,级联后可覆盖更大时间量程并结合粗计数拓展动态范围。TDC设计利用FPGA的专用进位链硬件,实现了亚纳秒级的时间测量精度,这是传统数字方法无法达到的。虽然需要校准,但其性能优势和数字集成的便利性使其成为高精度时间测量的首选方案。 2 CARRY4 核心结构与抽头延迟链原理 2.1 CARRY4 单元结构(Xilinx 7 系列 / UltraScale) 每个 CARRY4 包含 4 个 MUXCY 进位选择器与 4 个 XORCY 异或门,