Native Messaging(本地消息传递)

警告

重要提示:Chrome 将在所有平台上取消对 Chrome 应用程序的支持。 Chrome 浏览器和 Chrome 网上应用店将继续支持扩展。阅读公告并了解有关迁移应用程序的更多信息。

扩展程序和应用程序可以使用类似于其他消息传递 API 的 API 与本机应用程序交换消息(message passing APIs)。支持此功能的本机应用程序必须注册一个知道如何与扩展通信的本机消息传递主机。Chrome 在单独的进程中启动主机,并使用标准输入和标准输出流与其通信。

# 本地消息传递主机(Native messaging host)

为了注册本地消息传递主机,应用程序必须安装定义本地消息传递主机配置的清单文件。下面是清单文件的示例:

{
  "name": "com.my_company.my_application",
  "description": "My Application",
  "path": "C:\\Program Files\\My Application\\chrome_native_messaging_host.exe",
  "type": "stdio",
  "allowed_origins": [
    "chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/"
  ]
}

本机消息传递主机清单文件必须是有效的 JSON 并包含以下字段:

Name Description
name 本机消息传递主机的名称。客户端将此字符串传递给 runtime.connectNativeruntime.sendNativeMessage。此名称只能包含小写字母数字字符、下划线和点。名称不能以点开头或结尾,一个点后面不能跟另一个点。
description 简短的应用程序说明。
path 本机消息传递主机二进制文件的路径。在 Linux 和 OSX 上,路径必须是绝对路径。在 Windows 上,它可以相对于清单文件所在的目录。主机进程启动时将当前目录设置为包含主机二进制文件的目录。例如,如果此参数设置为 C:\Application\nm_host.exe,那么它将从当前目录 C:\Application\ 启动。
type 用于与本机消息传递主机通信的接口类型。目前这个参数只有一个可能的值:stdio。它表示 Chrome 应该使用 stdin 和 stdout 与主机通信。
allowed_origins 应该有权访问本机消息传递主机的扩展列表。不允许使用诸如 chrome-extension:/// 之类的通配符。

# 本机消息传递主机位置(Native messaging host location)

清单文件的位置取决于平台。

在 Windows 上,清单文件可以位于文件系统中的任何位置。应用程序安装程序必须创建注册表项HKEY_LOCAL_MACHINE\SOFTWARE\Google\Chrome\NativeMessagingHosts\_com.my_company.my_application_ or HKEY_CURRENT_USER\SOFTWARE\Google\Chrome\NativeMessagingHosts\_com.my_company.my_application_,并将该键的默认值设置为清单文件的完整路径。例如,使用以下命令:

REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.my_company.my_application" /ve /t REG_SZ /d "C:\path\to\nmh-manifest.json" /f

或使用以下 .reg 文件:

Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Google\Chrome\NativeMessagingHosts\com.my_company.my_application]
@="C:\\path\\to\\nmh-manifest.json"

当 Chrome 查找本地消息传递主机时,首先会查询 32 位注册表,然后是 64 位注册表。

在 OS X 和 Linux 上,本机消息传递主机的清单文件的位置因浏览器(Google Chrome 或 Chromium)而异。在固定位置查找系统范围的本机消息传递主机,而在用户配置文件目录(user profile directory)中名为 NativeMessagingHosts 的子目录中查找用户级本机消息传递主机。

  • OS X (system-wide)

    • Google Chrome: /Library/Google/Chrome/NativeMessagingHosts/_com.my_company.my_application_.json
    • Chromium: /Library/Application Support/Chromium/NativeMessagingHosts/_com.my_company.my_application_.json
  • OS X (user-specific, default path)

    • Google Chrome: ~/Library/Application Support/Google/Chrome/NativeMessagingHosts/_com.my_company.my_application_.json
    • Chromium: ~/Library/Application Support/Chromium/NativeMessagingHosts/_com.my_company.my_application_.json
  • Linux (system-wide)

    • Google Chrome: /etc/opt/chrome/native-messaging-hosts/_com.my_company.my_application_.json
    • Chromium: /etc/chromium/native-messaging-hosts/_com.my_company.my_application_.json
  • Linux (user-specific, default path)

    • Google Chrome: ~/.config/google-chrome/NativeMessagingHosts/_com.my_company.my_application_.json
    • Chromium: ~/.config/chromium/NativeMessagingHosts/_com.my_company.my_application_.json

# 本地消息传递协议( Native messaging protocol)

Chrome 在单独的进程中启动每个本地消息传递主机,并使用标准输入 (stdin) 和标准输出 (stdout) 与其通信。使用相同的格式在两个方向发送消息:每条消息都使用 JSON、UTF-8 编码进行序列化,并以本机字节顺序以 32 位消息长度开头。来自本机消息传递主机的单个消息的最大大小为 1 MB,主要是为了保护 Chrome 免受本机应用程序的不当行为。发送到本地消息传递主机的消息的最大大小为 4 GB。

本地消息传递主机的第一个参数是调用者的来源,通常是 chrome-extension://[允许扩展的 ID]。这允许本地消息传递主机在本地消息传递主机清单(native messaging host manifest)的 allowed_origins 键中指定多个扩展时识别消息的来源。警告:在 Windows 中,在 Chrome 54 及更早版本中,原点作为第二个参数而不是第一个参数传递。

当使用 runtime.connectNative 创建消息端口时,Chrome 会启动本机消息主机进程并保持其运行,直到端口被销毁。另一方面,当使用 runtime.sendNativeMessage 发送消息时,无需创建消息传递端口,Chrome 会为每条消息启动一个新的本地消息传递主机进程。在这种情况下,主机进程生成的第一条消息将作为对原始请求的响应进行处理,即 Chrome 会将其传递给调用 runtime.sendNativeMessage 时指定的响应回调。在这种情况下,本地消息传递主机生成的所有其他消息都将被忽略。

在 Windows 上,本机消息传递主机还会传递一个命令行参数,其中包含调用 chrome 本机窗口的句柄:--parent-window=<decimal handle value>。这使本机消息传递主机可以创建正确聚焦的本机 UI 窗口。

# 连接到本地应用程序( Connecting to a native application)

向本机应用程序发送消息和从本机应用程序接收消息与跨扩展消息传递非常相似。主要区别是使用runtime.connectNative 代替runtime.connect,使用runtime.sendNativeMessage 代替runtime.sendMessage。只有在应用的清单文件中声明了“nativeMessaging”权限时,才能使用这些方法。

以下示例创建了一个连接到本机消息传递主机 com.my_company.my_applicationruntime.Port 对象,开始侦听来自该端口的消息并发送一条传出消息:

var port = chrome.runtime.connectNative('com.my_company.my_application');
port.onMessage.addListener(function(msg) {
  console.log("Received" + msg);
});
port.onDisconnect.addListener(function() {
  console.log("Disconnected");
});
port.postMessage({ text: "Hello, my_application" });

runtime.sendNativeMessage 可用于在不创建端口的情况下向本机应用程序发送消息,例如:

chrome.runtime.sendNativeMessage('com.my_company.my_application',
  { text: "Hello" },
  function(response) {
    console.log("Received " + response);
  });

# 调试本机消息传递(Debugging native messaging)

当本地(native)消息主机启动失败、写入 stderr 或违反通信协议时,输出写入 Chrome 的错误日志。在 Linux 和 OS X 上,可以通过从命令行启动 Chrome 并在终端中查看其输出来轻松访问此日志。在 Windows 上,按照如何启用日志记录中的说明使用 --enable-logging(How to enable logging)。

以下是解决问题的一些错误和提示:

  • 无法启动本机消息传递主机。

    • 检查您是否有足够的权限来执行该文件。
  • 指定的本机消息传递主机名无效。

    • 检查名称是否包含任何无效字符。只允许使用小写字母数字字符、下划线和点。名称不能以点开头或结尾,一个点后面不能跟另一个点。
  • 本机主机已退出。

    • 在 Chrome 读取消息之前,连接到本地消息传递主机的管道已损坏。这很可能是从您的本地消息传递主机启动的。
  • 未找到指定的本机消息传递主机。

    • 扩展名和清单文件中的名称拼写是否正确?
    • 清单是否放在正确的目录中并具有正确的名称?有关预期格式,请参阅本机消息传递主机位置
    • 清单文件的格式是否正确?特别是,JSON 语法是否正确,值是否与本机消息传递主机清单的定义匹配?
    • 路径中指定的文件是否存在?在 Windows 上,路径可能是相对的,但在 OS X 和 Linux 上,路径必须是绝对的。
  • 本机消息传递主机主机名未注册。 (仅限 Windows)

    • 在 Windows 注册表中找不到本机消息传递主机。使用 regedit 仔细检查密钥是否真的创建并与本机消息传递主机位置记录的所需格式相匹配。
  • 禁止访问指定的本地消息传递主机。

    • 扩展的来源是否列在 allowed_origins 中?
  • 与本机消息传递主机通信时出错。

    • 这是一个非常常见的错误,表明本地消息传递主机中的通信协议实现不正确。
      • 确保 stdout 中的所有输出都遵守本机消息传递协议。如果您想打印一些用于调试的数据,请写入 stderr
      • 确保 32 位消息长度采用平台的本机整数格式(little-endian / big-endian)。
      • 消息长度不能超过 1024*1024。
      • 消息大小必须等于消息中的字节数。这可能与字符串的“长度”不同,因为字符可能由多个字节表示。
      • 仅限 Windows:确保程序的 I/O 模式设置为 O_BINARY。默认情况下,I/O 模式为 O_TEXT,这会破坏消息格式,因为换行符 (\n = 0A) 被替换为 Windows 样式的行尾 (\r\n = 0D 0A)。可以使用 __setmode 设置 I/O 模式。

# Examples(例子)

examples/api/nativeMessaging 目录包含一个示例应用程序,该应用程序使用本机消息传递与用作本机消息传递主机的 Python 脚本进行通信。示例主机的目录还包含用于安装/删除本机消息传递主机的脚本。

要试用该示例,请首先下载并解压缩示例应用程序示例主机。运行 install_host.bat (Windows) 或 install_host.sh (Linux / OS X) 以安装本机消息传递主机。然后加载应用程序并与应用程序交互。完成后,运行uninstall_host.bat 或uninstall_host.sh 以取消注册本机消息传递主机。

By.一粒技术服务

results matching ""

    No results matching ""