Electron 42.3.0:新协议查询 API 让桌面应用注册与发现更省心

2026-05-29 18 预计阅读时间:1 分钟
来源:oschina.net AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:7 分钟

Electron 42.3.0 刚刚发布。这个版本最值得注意的变化是新增了 app.getApplicationInfoForProtocol()——一个让开发者能直接查询系统协议注册信息的 API。对于需要处理自定义 URL 协议(比如 myapp://)的桌面应用来说,这补上了长期以来的一块短板:以前你只能"注册",没法方便地"查回来"。

协议注册的老痛点

桌面应用经常需要注册自定义协议,让浏览器或其他应用通过 myapp://open?file=xxx 这样的链接唤起自己。Electron 早就提供了 app.setAsDefaultProtocolClient() 来完成注册,但问题在于:

  • 注册之后,你不知道是否真的注册成功了
  • 你无法查询某个协议当前绑定的是哪个应用
  • 在多应用竞争同一协议时,缺乏判断当前状态的手段

开发者只能靠手动查注册表(Windows)或 lsregister dump(macOS)来确认,既麻烦又容易出错。

getApplicationInfoForProtocol() 做了什么

新 API 的用法非常直接——传入一个协议名,返回该协议当前默认处理应用的详细信息:

const { app } = require('electron')

// 查询 myapp:// 协议当前绑定的应用信息
app.getApplicationInfoForProtocol('myapp').then(info => {
  console.log(info)
  // 返回对象包含:name, path, iconPath 等字段
}).catch(err => {
  console.error('查询失败:', err)
})

返回的 info 对象至少包含应用名称和可执行路径,让你能判断:

  1. 协议是否已被注册
  2. 注册的是不是你的应用
  3. 如果不是你的应用,是哪个竞品占了位

这在安装向导、首次启动检测、协议冲突提示等场景下非常实用。

实战:协议注册 + 状态检测的完整流程

下面是一个可运行的 Electron 最小示例,演示注册协议后立即查询验证:

// main.js — Electron 协议注册与检测最小示例
const { app, BrowserWindow } = require('electron')

const PROTOCOL = 'myapp'

let mainWindow

app.whenReady().then(async () => {
  mainWindow = new BrowserWindow({
    width: 600,
    height: 400,
    webPreferences: { nodeIntegration: true, contextIsolation: false }
  })

  // 1. 注册自定义协议
  if (process.defaultApp) {
    // 开发模式下需要带上进程路径
    app.setAsDefaultProtocolClient(PROTOCOL, process.execPath, [process.argv[1]])
  } else {
    app.setAsDefaultProtocolClient(PROTOCOL)
  }

  // 2. 查询协议绑定状态(新 API)
  try {
    const info = await app.getApplicationInfoForProtocol(PROTOCOL)
    mainWindow.loadURL(
      `data:text/html;charset=utf-8,${encodeURIComponent(`
        <h2>协议注册检测结果</h2>
        <pre>${JSON.stringify(info, null, 2)}</pre>
        <p>协议 <strong>${PROTOCOL}://</strong> 已绑定到上述应用</p>
      `)}`
    )
  } catch (e) {
    mainWindow.loadURL(
      `data:text/html;charset=utf-8,${encodeURIComponent(`
        <h2>检测失败</h2>
        <p>${e.message}</p>
      `)}`
    )
  }
})

// 3. 处理从外部唤起的协议链接
app.on('open-url', (event, url) => {
  event.preventDefault()
  if (mainWindow) {
    mainWindow.loadURL(
      `data:text/html;charset=utf-8,${encodeURIComponent(`
        <h2>收到协议唤起</h2>
        <p>URL: ${url}</p>
      `)}`
    )
  }
})

对应的 package.json

{
  "name": "protocol-demo",
  "version": "1.0.0",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  },
  "devDependencies": {
    "electron": "^42.3.0"
  }
}

运行方式:

# 安装依赖
npm install

# 启动应用
npm start

# macOS 上测试协议唤起(终端执行)
open "myapp://open?doc=hello"

# Windows 上测试协议唤起(PowerShell 执行)
Start-Process "myapp://open?doc=hello"

启动后会看到窗口显示当前协议绑定的应用信息。如果返回的 info.path 与你的应用路径一致,说明注册成功;否则说明协议被其他应用占用了。

安装与升级注意事项

升级到 42.3.0 本身很简单:

# 直接升级
npm install electron@42.3.0

# 或锁定版本
npm install electron@42.3.0 --save-exact

但有几个点值得留意:

  • Chromium 与 Node 版本跟随:Electron 42 对应的 Chromium 和 Node.js 版本与 42.x 系列一致,如果你的代码依赖特定 Node API 版本,先核对 Electron 版本映射表
  • macOS 协议注册需要 Info.plist 配置setAsDefaultProtocolClient 在 macOS 上只负责注册到系统,但应用打包时仍需在 Info.plist 中声明 CFBundleURLTypes,否则 App Store 审核和某些系统版本下行为不一致。
  • Windows 需要管理员权限:在某些 Windows 版本上,协议注册涉及 HKCR 注册表写入,可能触发 UAC 提示。安装包阶段处理比运行时处理更稳妥。

什么时候该用这个新 API

几个典型场景:

场景 用法
安装向导中提示协议冲突 查询后告知用户"该协议已被 AppX 占用,是否覆盖"
首次启动时自检 确认协议确实绑定到了自己,而非被后续安装的其他应用抢走
多实例/多版本共存 判断当前协议指向的是哪个版本的可执行文件
卸载清理决策 查询确认后再决定是否调用 removeAsDefaultProtocolClient

小结

getApplicationInfoForProtocol() 不是一个大而全的重构,但它精准地补上了协议注册流程中"查状态"这一步。以前这块只能靠平台特定的黑魔法,现在有了统一 API,跨平台逻辑可以写得更干净。

如果你正在维护一个依赖自定义协议唤起的 Electron 应用,升级到 42.3.0 后建议把协议状态检测加入首次启动流程——几行代码就能避免用户遇到"点了链接却唤起了别的应用"的困惑。


相关推荐