本机消息传送

为了与安装在用户设备上的本机 Win32 应用通信,扩展使用类似于另一 条消息传递 API 的 API。 本机应用主机使用标准输入和标准输出发送和接收带有扩展的消息。

使用本机消息传送的扩展安装在 Microsoft Edge 中,类似于任何其他扩展。 但是,本机应用不由 Microsoft Edge 安装或管理。

若要获取扩展和本机应用主机,有两种不同的分发模型:

  • 将扩展和主机打包在一起。 用户安装包时,将同时安装扩展和主机。

  • 或者,使用 Microsoft Edge 加载项网站安装扩展,扩展会提示用户安装主机。

若要创建扩展以使用本机应用主机发送和接收消息,请执行以下步骤。

步骤 1:向扩展清单添加权限

nativeMessaging 权限添加到扩展的 manifest.json 文件。

这是 扩展清单文件,而不是 本机消息主机清单文件,稍后部分将对此进行介绍。

下面是一个 示例 manifest.json 文件:

{
    "name": "Native Messaging Example",
    "version": "1.0",
    "manifest_version": 3,
    "description": "Send a message to a native app.",
    "app": {
        "launch": {
            "local_path": "main.html"
        }
    },
    "icons": {
        "128": "icon-128.png"
    },
    "permissions": ["nativeMessaging"]
}

步骤 2:创建本机消息主机清单文件

本机应用必须提供本机消息主机清单文件。 本机消息主机清单文件包含以下信息:

  • 本机消息主机运行时的路径。

  • 与扩展通信的方法。

  • 它与之通信的允许扩展的列表。

浏览器读取并验证本机消息主机清单。 浏览器不会安装或管理本机消息主机清单文件。

本机消息主机清单文件不同于属于 Microsoft Edge 扩展的清单 V3 或 V2 文件。

本机消息主机清单文件的示例:

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

本机消息主机清单文件必须是包含以下键的有效 JSON 文件:

详细信息
name 指定本机消息传送主机的名称。 客户端将字符串传递给 runtime.connectNativeruntime.sendNativeMessage
该值只能包含小写字母数字字符、下划线和点。
该值不得以点 () 句点开头或结尾,并且一个点不能后跟另一个点。
description 描述应用。
path 指定本机消息主机二进制文件的路径。
在 Windows 设备上,可以使用包含本机消息传送主机清单文件的目录的相对路径。
在 macOS 和 Linux 上,路径必须是绝对路径。
主机进程从当前目录设置为包含主机二进制文件的目录开始。 例如, (Windows) ,如果 参数设置为 C:\App\nm_host.exe,则使用当前目录 (C:\App\) 启动二进制文件。
type 指定用于与本机消息传送主机通信的接口类型。 值指示 Microsoft Edge 使用 stdinstdout 与主机通信。 唯一可接受的值为 stdio
allowed_origins 指定有权访问本机消息传送主机的扩展的列表。 若要打开应用以标识扩展并与之通信,请在本机消息主机清单文件中设置以下值:
"allowed_origins": ["chrome-extension://{microsoft_catalog_extension_id}"]

旁加载扩展以使用主机测试本机消息传送。 若要在开发期间旁加载扩展并检索 microsoft_catalog_extension_id

  1. 转到 edge://extensions,然后打开 “开发人员模式 切换”按钮。

  2. 选择“ 加载解压缩”,然后选择要旁加载的扩展包。

  3. 单击“确定”

  4. 转到页面并 edge://extensions 验证扩展是否已列出。

  5. microsoft_catalog_extension_id 页面上的扩展列表 (ID) 复制密钥。

准备好向用户分发扩展时,请将扩展发布到 Microsoft Edge 加载项网站。 已发布扩展的扩展 ID 可能与旁加载扩展时使用的 ID 不同。 如果 ID 发生更改,请使用已发布扩展的 ID 在本机消息主机清单文件中更新 allowed_origins

步骤 3:将本机消息主机清单文件复制到系统

最后一步涉及将本机消息主机清单文件复制到计算机,并确保正确配置此清单文件。 若要确保本机消息主机清单文件位于预期位置,请执行以下步骤。 位置因平台而异。

在 Linux 和 macOS 上:

  • 请确保提供对本机消息主机清单文件的 读取 权限。
  • 请确保在主机运行时上提供 运行 权限。

本机消息主机清单文件可能位于文件系统中的任何位置。 应用安装程序必须创建注册表项,并将键的默认值设置为本机消息主机清单文件的完整路径。

以下位置是注册表项的示例:

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Edge\NativeMessagingHosts\com.my_company.my_app

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Edge\NativeMessagingHosts\com.my_company.my_app

若要使用清单键将注册表项添加到目录,请执行以下操作之一:

  • 在命令提示符下运行命令:

    REG ADD "HKCU\Software\Microsoft\Edge\NativeMessagingHosts\com.my_company.my_app" /ve /t REG_SZ /d "C:\path\to\nmh-manifest.json" /f
    
  • 或者,创建一个 .reg 文件并运行它,如下所示:

    1. 将以下命令复制到文件中 .reg

      Windows Registry Editor Version 5.00
      [HKEY_CURRENT_USER\Software\Microsoft\Edge\NativeMessagingHosts\com.my_company.my_app]
      @="C:\\path\\to\\nmh-manifest.json"
      
    2. .reg运行文件。 如果作为批处理脚本的一部分运行创建 .reg 的文件,请确保使用管理员命令提示符运行它。

Microsoft Edge 查询 HKEY_CURRENT_USER 根密钥,后跟 HKEY_LOCAL_MACHINE。 在这两个键中,首先搜索 32 位注册表,然后搜索 64 位注册表以标识本机消息传送主机。 注册表项指定本机消息主机清单文件的位置。

如果 Microsoft Edge 的注册表项没有本机消息主机清单文件的位置,Chromium和 Chrome 注册表位置将用作回退选项。

如果 Microsoft Edge 在前面列出的任一位置找到注册表项,则不会查询以下代码片段中列出的位置。

注册表位置的搜索顺序为:

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Edge\NativeMessagingHosts\
HKEY_CURRENT_USER\SOFTWARE\Chromium\NativeMessagingHosts\
HKEY_CURRENT_USER\SOFTWARE\Google\Chrome\NativeMessagingHosts\

HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Edge\NativeMessagingHosts\
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Chromium\NativeMessagingHosts\
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Google\Chrome\NativeMessagingHosts\

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Edge\NativeMessagingHosts\
HKEY_LOCAL_MACHINE\SOFTWARE\Chromium\NativeMessagingHosts\
HKEY_LOCAL_MACHINE\SOFTWARE\Google\Chrome\NativeMessagingHosts\

WOW6432Node 注册表节点

HKEY_CURRENT_USER\SOFTWARE\WOW6432Node注册表节点不会在 64 位计算机上搜索,因为注册表对其工作的方式不同。 有关详细信息,请参阅注册表项 受 Windows 安装影响的 Windows (WOW) 对多个处理器体系结构的支持

这两个存储区所需的扩展 ID

如果在 Microsoft Edge 加载项和 Chrome Web Store 上具有扩展,则必须在本机消息主机清单文件的 中添加 allowed_origins 对应于这两个存储的扩展 ID。 这是必需的,因为仅读取与找到的第一个注册表位置对应的本机消息主机清单文件。

本机消息传送协议

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

本机消息传送主机的第一个参数是调用方的来源,通常为 chrome-extension://[ID of allowed extension]。 这允许本机消息主机在本机消息主机清单的键中 allowed_origins 指定多个扩展时标识消息源;请参阅上面的 步骤 2:创建本机消息主机清单文件

在 Windows 上,本机消息传送主机还传递了命令行参数,该参数具有对调用 Microsoft Edge 本机窗口的句柄: --parent-window=<decimal handle value>。 这允许本机消息传送主机创建正确父级的本机 UI 窗口。 请注意,如果调用上下文是服务辅助角色,则此值将为 0。

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

连接到本机应用程序

向本机应用程序发送消息和从本机应用程序接收消息与跨扩展消息传送非常相似。 main区别在于,runtime.connectNative使用 而不是 runtime.connect,使用 runtime.sendNativeMessage 而不是 runtime.sendMessage

若要使用这些方法, nativeMessaging 必须在扩展的清单文件中声明权限;请参阅上面的 步骤 1:向扩展清单添加权限

这些方法在内容脚本中不可用,仅在扩展的页面和服务辅助角色中可用。 如果要从内容脚本与本机应用程序通信,请将消息发送给服务辅助角色,以将其传递到本机应用程序。

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

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);
  }
);

调试本机消息传送

发生某些本机消息传送失败时,输出将写入 Microsoft Edge 的错误日志。 这包括本机消息传送主机无法启动、写入 stderr 或违反通信协议时。 在 Linux 和 macOS 上,可以通过从命令行启动 Microsoft Edge 并在终端中监视其输出来轻松访问此日志。 在 Windows 上,如--enable-logging如何启用日志记录中所述使用。

下面是一些常见错误和解决这些问题的提示:

无法启动本机消息传送主机。

检查是否有足够的权限来执行本机消息主机文件。

指定的本机消息主机名无效。

检查名称是否包含无效字符。 仅允许使用小写字母数字字符、下划线和点 (句点) 。 名称不能以点开头或结尾,并且一个点不能后跟另一个点。

本机主机已退出。

在 Microsoft Edge 读取消息之前,指向本机消息主机的管道已中断。 这很可能是从本机消息传送主机启动的。

找不到指定的本机消息传送主机。

检查以下内容:

  • 扩展和清单文件中的名称拼写是否正确?

  • 清单是否位于正确的目录中且名称正确? 有关预期格式,请参阅 本机消息传送主机位置

  • 清单文件的格式是否正确? 具体而言,根据上面的步骤 2:创建本机消息主机清单文件,JSON 是否有效且格式正确,并且这些值是否与本机消息主机清单的定义匹配?

  • 中指定的 path 文件是否存在? 在 Windows 上,路径可能是相对路径,但在 macOS 和 Linux 上,路径必须是绝对路径。

未注册本机消息传送 主机主机名 。 (仅限 Windows)

在 Windows 注册表中找不到本机消息传送主机。 使用密钥是否真正创建并匹配本机消息主机位置记录的所需格式的双重检查regedit

禁止访问指定的本机消息传送主机。

扩展的源是否在 中 allowed_origins列出?

与本机消息传送主机通信时出错。

这表示本机消息传送主机中的通信协议实现不正确。

  • 请确保 中的所有 stdout 输出都遵循 本机消息传送协议。 如果要打印一些数据以进行调试,请写入 stderr

  • 确保 32 位消息长度采用平台的本机整数格式, (little-endian 或 big-endian) 。

  • 消息长度不能超过 1024*1024。

  • 消息大小必须等于消息中的字节数。 这可能不同于字符串的“长度”,因为字符可能由多个字节表示。

  • 仅限 Windows: 确保程序的 I/O 模式设置为 O_BINARY。 默认情况下,I/O 模式为 O_TEXT,这会损坏消息格式,因为换行符 ( = \n0A) 替换为 windows 样式的行尾 (\r\n = 0D 0A) 。 可以使用 设置 __setmodeI/O 模式。

注意

此页面的部分内容是基于 Google 创建和 共享 的工作进行的修改,并根据 Creative Commons 署名 4.0 国际许可中所述的条款使用。 原始页面 在此处找到。

Creative Commons 许可证 此作品根据 Creative Commons 署名 4.0 国际许可获得许可