chrome-extensions-samples 实战:Native Messaging 原生消息通信完整指南(echo 主机安装与协议解析)

发布时间:2026/9/21 19:20:32
chrome-extensions-samples 实战:Native Messaging 原生消息通信完整指南(echo 主机安装与协议解析) chrome-extensions-samples 实战Native Messaging 原生消息通信完整指南echo 主机安装与协议解析【免费下载链接】chrome-extensions-samplesChrome Extensions Samples项目地址: https://gitcode.com/gh_mirrors/ch/chrome-extensions-samples本文基于chrome-extensions-samples仓库中的 Native Messaging 示例完整讲解 Chrome 扩展/应用如何通过原生消息Native MessagingAPI 与本地原生程序通信包括消息主机的清单文件结构、Windows 与 Mac/Linux 双平台安装与卸载流程、扩展端connectNative调用链以及原生主机端基于标准输入输出实现的 4 字节长度前缀 JSON 报文协议。读完本文你将能独立复现并部署一个可双向收发的原生消息回显echo示例。示例概览扩展与原生程序如何握手Native Messaging 允许 Web 扩展Manifest V2 时代也支持 Chrome App与用户机器上安装的原生可执行程序直接交换消息适用于需要调用系统能力、本地硬件或已有桌面应用的场景。本仓库的示例位于_archive/mv2/api/nativeMessaging/其对应的 Manifest V3 版本位于 api-samples/nativeMessaging/目录结构如下_archive/mv2/api/nativeMessaging/ ├── README.md # 示例说明与安装指引本文依据的主体文档 ├── app/ # 扩展/应用端Manifest V2 Chrome App │ ├── manifest.json │ ├── main.html │ ├── main.js │ └── icon-128.png └── host/ # 原生消息主机Native Messaging Host ├── com.google.chrome.example.echo.json # Mac/Linux 主机清单 ├── com.google.chrome.example.echo-win.json # Windows 主机清单 ├── install_host.sh # Mac/Linux 安装脚本 ├── uninstall_host.sh # Mac/Linux 卸载脚本 ├── install_host.bat # Windows 安装脚本 ├── uninstall_host.bat # Windows 卸载脚本 ├── native-messaging-example-host # 主机本体Python 3 实现 └── native-messaging-example-host.bat # Windows 启动包装脚本整个示例的通信链路为Chrome扩展端→ 原生消息主机manifest 指向的可执行程序→ 回显消息。主机名为com.google.chrome.example.echo扩展端与主机端均围绕该名字建立绑定关系。按 README.md 的说明要让示例跑起来必须先安装 host 目录下的原生消息主机否则扩展端调用chrome.runtime.connectNative()会因找不到主机而连接失败。原生消息主机的清单文件注册的关键Chrome 靠一份 JSON 清单manifest定位原生主机这份清单必须被安装到操作系统指定的目录或注册表位置。本示例提供了两个平台版本Mac/Linux 版host/com.google.chrome.example.echo.json{ name: com.google.chrome.example.echo, description: Chrome Native Messaging API Example Host, path: HOST_PATH, type: stdio, allowed_origins: [ chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/ ] }Windows 版host/com.google.chrome.example.echo-win.json{ name: com.google.chrome.example.echo, description: Chrome Native Messaging API Example Host, path: native-messaging-example-host.bat, type: stdio, allowed_origins: [ chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/ ] }各字段含义如下字段作用本示例取值name主机唯一标识名扩展端connectNative(hostName)必须与之一致com.google.chrome.example.echodescription主机用途说明Chrome Native Messaging API Example Hostpath主机可执行程序的绝对路径Linux/Mac或启动命令WindowsLinux/Mac 为HOST_PATH占位符由安装脚本替换Windows 为native-messaging-example-host.battype通信通道类型原生消息必须为stdiostdioallowed_origins允许连接本主机的扩展 ID 白名单chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/两点需要特别说明扩展 ID 绑定allowed_origins中硬编码了扩展 IDknldjmfmopnpolahpmmgbagdohdnhkik。该 ID 由 app/manifest.json 顶部的key字段注释中同样标注了该 ID决定——也就是固定 key 的扩展 ID 可预测这一机制。如果你改动了key或使用未签名的临时加载方式扩展 ID 会变化必须同步更新清单中的allowed_origins否则 Chrome 会拒绝建立连接。Windows 路径差异Windows 清单的path指向native-messaging-example-host.bat一个调用 Python 解释器启动主机的批处理脚本因为注册表安装方式写入的是脚本所在目录的相对名而 Mac/Linux 清单的path在安装时会被替换成native-messaging-example-host的绝对路径。安装主机Windows 注册表方式在 Windows 上运行 host 目录下的 install_host.bat 即可完成当前用户的安装:: Change HKCU to HKLM if you want to install globally. :: %~dp0 is the directory containing this bat script and ends with a backslash. REG ADD HKCU\Software\Google\Chrome\NativeMessagingHosts\com.google.chrome.example.echo /ve /t REG_SZ /d %~dp0com.google.chrome.example.echo-win.json /f脚本原理与 README.md 描述一致在注册表HKEY_CURRENT_USER\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.google.chrome.example.echo下创建键将该键的默认值/ve设置为指向host\com.google.chrome.example.echo-win.json的完整路径通过%~dp0取脚本所在目录末尾带反斜杠Chrome 启动时读取该注册表位置按清单中的path启动主机。扩展说明全局安装如需为所有用户安装把脚本中的HKCU改为HKLM即可注册表路径变为HKLM\Software\Google\Chrome\NativeMessagingHosts\...。注意 README 明确提示机器上需要安装 Python因为 Windows 主机是通过 native-messaging-example-host.bat 调用python来运行主机的echo off python %~dp0/native-messaging-example-host %*卸载运行 uninstall_host.bat它会同时删除 HKCU 与 HKLM 两处注册表项REG DELETE HKCU\Software\Google\Chrome\NativeMessagingHosts\com.google.chrome.example.echo /f REG DELETE HKLM\Software\Google\Chrome\NativeMessagingHosts\com.google.chrome.example.echo /f安装主机Mac 与 Linux 目录方式在 Mac 和 Linux 上直接运行 host/install_host.shhost/install_host.sh脚本首先根据系统与运行权限计算目标目录从源码可见完整的分支逻辑平台普通用户仅当前用户root/admin全用户macOS$HOME/Library/Application Support/Google/Chrome/NativeMessagingHosts/Library/Google/Chrome/NativeMessagingHostsLinux$HOME/.config/google-chrome/NativeMessagingHosts/etc/opt/chrome/native-messaging-hosts随后脚本依次执行mkdir -p $TARGET_DIR创建目录cp $DIR/$HOST_NAME.json $TARGET_DIR拷贝主机清单用sed -i -e s/HOST_PATH/$ESCAPED_HOST_PATH/将清单中的HOST_PATH占位符替换为主机脚本的绝对路径chmod or让所有用户可读清单root 安装时还会对主机脚本执行chmod ax赋予执行权限输出安装成功信息。对应地host/uninstall_host.sh 会删除目标目录下的com.google.chrome.example.echo.json完成卸载host/uninstall_host.shREADME 特别说明默认只安装给运行脚本的用户若以sudo host/install_host.sh执行则会安装到系统级目录供所有用户使用。扩展端发起连接与收发消息扩展端代码位于 app/main.js核心是调用chrome.runtime.connectNative(hostName)建立长连接。关键逻辑如下var port null; function connect() { var hostName com.google.chrome.example.echo; appendMessage(Connecting to native messaging host b hostName /b) port chrome.runtime.connectNative(hostName); port.onMessage.addListener(onNativeMessage); port.onDisconnect.addListener(onDisconnected); updateUiState(); } function sendNativeMessage() { message {text: document.getElementById(input-text).value}; port.postMessage(message); appendMessage(Sent message: b JSON.stringify(message) /b); } function onNativeMessage(message) { appendMessage(Received message: b JSON.stringify(message) /b); } function onDisconnected() { appendMessage(Failed to connect: chrome.runtime.lastError.message); port null; updateUiState(); }调用链与要点连接connectNative(hostName)返回一个Port对象hostName必须与主机清单中的name完全一致即com.google.chrome.example.echo收消息通过port.onMessage.addListener(onNativeMessage)监听原生主机发来的消息发消息通过port.postMessage(message)发送 JSON 对象本示例发送{text: ...}断线处理port.onDisconnect触发时通过chrome.runtime.lastError.message获取失败原因典型如主机未安装、扩展 ID 不匹配并将port置空以复位 UI 状态UI 状态机updateUiState()根据port是否存在切换Connect / Send按钮与输入框的显隐避免在未连接时发送消息。界面app/main.html提供了 Connect 按钮、文本输入框、Send 按钮以及用于回显收发记录的#response区域。扩展本身需要声明nativeMessaging权限见 app/manifest.json{ name: Native Messaging Example, version: 1.0, manifest_version: 2, description: Send a message to a native application., app: { launch: { local_path: main.html } }, permissions: [nativeMessaging] }注意这是一个 Manifest V2 时代的 Chrome App使用app.launch.local_path启动入口。在 Manifest V3 扩展中权限声明位置不变permissions: [nativeMessaging]而连接 API 同样为chrome.runtime.connectNative——仓库中 api-samples/nativeMessaging/extension/ 即提供了 MV3 版本的对应实现可对照阅读。原生主机端stdio 通道与 4 字节长度前缀协议原生主机本体是 Python 3 脚本 host/native-messaging-example-host它以type: stdio与 Chrome 通信通过标准输入读取扩展发来的消息通过标准输出写回响应。通信协议Native Messaging 的标准报文格式在源码中有完整实现发送消息向扩展def send_message(message): # Write message size. sys.stdout.buffer.write(struct.pack(I, len(message))) # Write the message itself. sys.stdout.write(message) sys.stdout.flush()接收消息来自扩展def read_thread_func(queue): while 1: # Read the message length (first 4 bytes). text_length_bytes sys.stdin.buffer.read(4) if len(text_length_bytes) 0: ... sys.exit(0) # Unpack message length as 4 byte integer. text_length struct.unpack(I, text_length_bytes)[0] # Read the text (JSON object) of the message. text sys.stdin.buffer.read(text_length).decode(utf-8) ...即每条消息的编码为前 4 字节原生小端I是消息体字节长度其后紧跟 UTF-8 编码的 JSON 文本。收发双方都必须遵循这一帧格式才能保证 stdin/stdout 通道不会错位。其余实现要点Windows 二进制模式脚本开头针对win32平台调用msvcrt.setmode将 stdin/stdout 切换为O_BINARY避免 Windows 文本模式对流内容的改写破坏二进制帧回显与退出收到{text:exit}时退出循环在无图形界面headless模式下主机直接把收到的 JSON 包装成{echo: 原消息}返回Tkinter 图形界面若系统装有 Tkinter主机启动一个NativeMessagingWindow文本框 输入框 Send 按钮收到的消息会显示在窗口中也可手动输入消息回发给扩展——这正是示例名 echo 的交互体验双向消息都会在扩展端 main.html 的响应区与主机窗口中同步可见线程模型主线程运行 Tkinter 事件循环另起守护线程read_thread_func持续读取 stdin通过queue把消息投递给 UI 线程处理避免阻塞消息读取。运行与验证步骤结合 README.md 与源码完整运行流程如下安装原生主机二选一Windows在 host 目录运行install_host.bat需安装 PythonMac/Linux运行host/install_host.sh全局安装可加sudo在 Chrome 中加载扩展/应用目录_archive/mv2/api/nativeMessaging/app/chrome://extensions开启开发者模式后加载已解压的扩展程序MV3 版本则加载 api-samples/nativeMessaging/extension/打开应用主界面点击Connect——若主机安装成功扩展会建立到com.google.chrome.example.echo的连接在输入框键入文本并点击Send扩展端界面与原生主机窗口Tkinter 可用时都会显示收到的消息实现双向回显需要清理时分别运行uninstall_host.bat或host/uninstall_host.sh卸载主机。若连接失败优先排查三个位置allowed_origins中的扩展 ID 是否与当前加载扩展一致、清单path指向的程序是否存在且可执行、Windows 注册表/HKCU 或系统目录中的清单是否就位。小结这个 echo 示例完整覆盖了 Native Messaging 的全链路要素主机清单的name/path/type/allowed_origins配置、Windows 注册表与 Mac/Linux 目录两种注册机制、扩展端connectNative的收发与断线处理以及主机端基于 4 字节长度前缀 JSON 的 stdio 帧协议。对照仓库中 app/ 与 host/ 的源码可以清晰理解 Chrome 与本地程序之间每一次消息往返的底层路径——这也是开发真实原生消息主机如调用本地 CLI、系统 API 或专用硬件时可直接复用的最小可运行模板。【免费下载链接】chrome-extensions-samplesChrome Extensions Samples项目地址: https://gitcode.com/gh_mirrors/ch/chrome-extensions-samples创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考