ネイティブ メッセージング

拡張機能は、他のメッセージ パッシング API と同様の API を使用して、ネイティブ アプリケーションとメッセージを交換できます。この機能をサポートするネイティブ アプリケーションは、拡張機能と通信できるネイティブ メッセージング ホストを登録する必要があります。Chrome はホストを別のプロセスで起動し、標準入力ストリームと標準出力ストリームを使用してホストと通信します。

ネイティブ メッセージング ホスト

ネイティブ メッセージング ホストを登録するには、アプリケーションでネイティブ メッセージング ホストの構成を定義するファイルを保存する必要があります。

ファイルの例を次に示します。

{
  "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
ネイティブ メッセージング ホストの名前。クライアントはこの文字列を runtime.connectNative() または runtime.sendNativeMessage() に渡します。この名前に使用できるのは、小文字の英数字、アンダースコア、ドットのみです。名前の先頭または末尾にドットを使用することはできません。また、ドットの後に別のドットを続けることもできません。
description
アプリケーションの簡単な説明。
path
ネイティブ メッセージング ホスト バイナリのパス。Linux と macOS では、パスは絶対パスである必要があります。Windows では、マニフェスト ファイルを含むディレクトリの相対パスにできます。ホスト プロセスは、現在のディレクトリがホスト バイナリを含むディレクトリに設定された状態で開始されます。たとえば、このパラメータが C:\Application\nm_host.exe に設定されている場合、現在のディレクトリ `C:\Application` で開始されます。
type
ネイティブ メッセージング ホストとの通信に使用されるインターフェースのタイプ。このパラメータには stdio という値のみを指定できます。これは、Chrome がホストとの通信に stdinstdout を使用することを示します。
allowed_origins
ネイティブ メッセージング ホストにアクセスできる拡張機能のリスト。allowed-origins の値にワイルドカードを含めることはできません。

ネイティブ メッセージング ホストの場所

マニフェスト ファイルの場所はプラットフォームによって異なります。

Windows では、マニフェスト ファイルはファイル システム内の任意の場所に配置できます。アプリケーション インストーラは、HKEY_LOCAL_MACHINE\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.my_company.my_application または 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 ビットのレジストリがクエリされます。

macOSLinux では、ネイティブ メッセージング ホストのマニフェスト ファイルの場所はブラウザ(Google Chrome または Chromium)によって異なります。システム全体のネイティブ メッセージング ホストは固定の場所で検索されますが、ユーザーレベルのネイティブ メッセージング ホストはユーザー プロファイル ディレクトリNativeMessagingHosts/ サブディレクトリで検索されます。

macOS(システム全体)
Google Chrome: /Library/Google/Chrome/NativeMessagingHosts/com.my_company.my_application.json
Chromium: /Library/Application Support/Chromium/NativeMessagingHosts/com.my_company.my_application.json
macOS(ユーザー固有、デフォルトのパス)
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(システム全体)
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(ユーザー固有、デフォルトのパス)
Google Chrome: ~/.config/google-chrome/NativeMessagingHosts/com.my_company.my_application.json
Chromium: ~/.config/chromium/NativeMessagingHosts/com.my_company.my_application.json

ネイティブ メッセージング プロトコル

Chrome は、各ネイティブ メッセージング ホストを別のプロセスで起動し、標準入力(stdin)と標準出力(stdout)を使用して通信します。同じ形式が双方向のメッセージ送信に使用されます。各メッセージは JSON を使用してシリアル化され、UTF-8 でエンコードされ、ネイティブ バイト順の 32 ビット メッセージ長が前に付加されます。ネイティブ メッセージング ホストからの 1 つのメッセージの最大サイズは 1 MB です。これは主に、不正な動作をするネイティブ アプリケーションから Chrome を保護するためです。ネイティブ メッセージング ホストに送信されるメッセージの最大サイズは 64 MiB です。

ネイティブ メッセージング ホストの最初の引数は、呼び出し元のオリジンです。通常は chrome-extension://[ID of allowed extension] です。これにより、ネイティブ メッセージング ホスト マニフェストallowed_origins キーで複数の拡張機能が指定されている場合に、ネイティブ メッセージング ホストがメッセージの送信元を特定できるようになります。

Windows では、ネイティブ メッセージング ホストに、呼び出し元の Chrome ネイティブ ウィンドウのハンドルを含むコマンドライン引数 --parent-window=<decimal handle value> も渡されます。これにより、ネイティブ メッセージング ホストは、正しく親設定されたネイティブ UI ウィンドウを作成できます。呼び出しコンテキストがサービス ワーカーの場合、この値は 0 になります。

runtime.connectNative() を使用してメッセージング ポートが作成されると、Chrome はネイティブ メッセージング ホスト プロセスを開始し、ポートが破棄されるまで実行し続けます。一方、メッセージング ポートを作成せずに runtime.sendNativeMessage() を使用してメッセージを送信すると、Chrome はメッセージごとに新しいネイティブ メッセージング ホスト プロセスを開始します。この場合、ホストプロセスによって生成された最初のメッセージは元のリクエストのレスポンスとして処理され、Chrome は runtime.sendNativeMessage() の呼び出し時に指定されたレスポンス コールバックに渡します。この場合、ネイティブ メッセージング ホストによって生成された他のすべてのメッセージは無視されます。

ネイティブ アプリケーションへの接続

ネイティブ アプリケーションとのメッセージの送受信は、クロス拡張機能メッセージングとよく似ています。主な違いは、runtime.connect() の代わりに runtime.connectNative() が使用され、runtime.sendMessage() の代わりに runtime.sendNativeMessage() が使用されることです。

これらのメソッドを使用するには、拡張機能のマニフェスト ファイルで「nativeMessaging」権限を宣言する必要があります。

これらのメソッドは、コンテンツ スクリプト内では使用できません。拡張機能のページとサービス ワーカー内でのみ使用できます。コンテンツ スクリプトからネイティブ アプリケーションに通信する場合は、サービス ワーカーにメッセージを送信して、ネイティブ アプリケーションに渡します。

次の例では、ネイティブ メッセージング ホスト com.my_company.my_application に接続された runtime.Port オブジェクトを作成し、そのポートからのメッセージのリスニングを開始して、1 つの送信メッセージを送信します。

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

ネイティブ メッセージングをデバッグする

特定のネイティブ メッセージング エラーが発生すると、出力が Chrome のエラーログに書き込まれます。これには、ネイティブ メッセージング ホストの起動に失敗した場合、stderr に書き込んだ場合、通信プロトコルに違反した場合などが含まれます。Linux と macOS では、コマンドラインから Chrome を起動し、ターミナルで出力を確認することで、このログにアクセスできます。Windows では、ロギングを有効にする方法で説明されているように、--enable-logging を使用します。

一般的なエラーとその解決方法のヒントは次のとおりです。

ネイティブ メッセージング ホストを起動できませんでした。

ネイティブ メッセージング ホストファイルを実行するのに十分な権限があるかどうかを確認します。

無効なネイティブ メッセージング ホスト名が指定されました。

名前に無効な文字が含まれていないか確認します。英小文字、アンダースコア、ドットのみ使用できます。名前の先頭または末尾にドットを使用することはできません。また、ドットの後に別のドットを続けることはできません。

ネイティブ ホストが終了しました。

メッセージが Chrome で読み取られる前に、ネイティブ メッセージング ホストへのパイプが切断されました。これは、ネイティブ メッセージング ホストから開始される可能性が最も高いです。

指定されたネイティブ メッセージング ホストが見つかりません。

以下を確認します。

  • 拡張機能とマニフェスト ファイルで名前のスペルが正しく入力されていますか?
  • マニフェストが正しいディレクトリに正しい名前で存在するかどうかを確認します。適切な形式については、ネイティブ メッセージング ホストの場所をご覧ください。
  • マニフェスト ファイルの形式は正しいですか?特に、JSON が有効で形式が正しく、値がネイティブ メッセージング ホスト マニフェストの定義と一致しているかどうかを確認します。
  • path で指定されたファイルは存在しますか?Windows では相対パスを使用できますが、macOS と Linux では絶対パスを使用する必要があります。

ネイティブ メッセージング ホスト ホスト名が登録されていません。(Windows のみ)

ネイティブ メッセージング ホストが Windows レジストリに見つかりませんでした。regedit を使用して、キーが実際に作成され、ネイティブ メッセージング ホストの場所に記載されている必要な形式と一致しているかどうかを再確認します。

指定されたネイティブ メッセージング ホストへのアクセスは禁止されています。

拡張機能のオリジンは allowed_origins に記載されていますか?

ネイティブ メッセージング ホストとの通信中にエラーが発生しました。

これは、ネイティブ メッセージング ホストでの通信プロトコルの実装が正しくないことを示します。

  • stdout のすべての出力がネイティブ メッセージング プロトコルに準拠していることを確認します。デバッグ目的でデータを印刷する場合は、stderr に書き込みます。
  • 32 ビットのメッセージ長がプラットフォームのネイティブ整数形式(リトルエンディアン / ビッグエンディアン)であることを確認します。
  • メッセージの長さは 1,024*1,024 を超えないようにしてください。
  • メッセージ サイズは、メッセージのバイト数と等しくなければなりません。文字が複数のバイトで表される場合があるため、文字列の「長さ」とは異なる場合があります。
  • Windows のみ: プログラムの I/O モードが O_BINARY に設定されていることを確認します。デフォルトでは、I/O モードは O_TEXT です。このモードでは、改行(\n = 0A)が Windows スタイルの行末(\r\n = 0D 0A)に置き換えられるため、メッセージ形式が破損します。I/O モードは __setmode を使用して設定できます。