10

runtime.connectNativeandを使用して Chrome 拡張機能を実装しようとしていpostMessageます。Chrome のドキュメントに従って、ネイティブ メッセージングの例をダウンロードし、ネイティブ アプリを C++ を使用するように変更しました。

ただし、ネイティブ アプリは Chrome 拡張機能からのメッセージを受信できません。

一方、printf関数を使用するネイティブ アプリが Chrome 拡張機能にメッセージを書き込むと、拡張機能は受信できず、コンソールにメッセージが表示されます。

問題を解決する方法はありますか?

4

2 に答える 2

25

実際に試したことについて多くの情報を提供していないので、Chrome 拡張機能、ネイティブ メッセージング ホストを実装し、それらの間の通信を確立するために必要な手順を説明するために最善を尽くします。(Chrome Native Messaging の詳細については、次のリンクを参照してください: Chrome Native Messaging How to .

クロームエクステンション

まず、Chrome 拡張機能をセットアップする必要があります。これは非常に単純な拡張機能であるため、manifest.jsonファイル (これは拡張機能のマニフェスト ファイルであることに注意してください。ネイティブ ホストにも独自のマニフェスト ファイルがあります) と background.js JavaScript 実装のみが必要です。

以下は、 manifest.jsonファイルのサンプルです。

{
  "name": "Test extension",
  "description": "Native messaging test",
   "permissions": [
                    "nativeMessaging",
                    "tabs",
                    "activeTab",
                    "background",
                    "http://*/", "https://*/"
                    ],
  "background": {
    "scripts": ["background.js"]
  },
  "version": "1.0",
  "minimum_chrome_version": "29",
  "manifest_version": 2
}

ここで重要なことは、実装が background.js で提供されること、サポートされる Chrome の最小バージョンが 29 であること、HTTP と HTTPS の両方がサポートされることです。

次に、background.jsファイルには次の内容が含まれます。

var port = chrome.runtime.connectNative('com.dolby.native_messaging_host');

port.onMessage.addListener(function(msg) {
  console.log(msg.text);
});

port.onDisconnect.addListener(function() {
  console.log("Disconnected");
});

port.postMessage({"text":"This is message from Chrome extension"});

コード自体は一目瞭然です。com.dolby.native_messaging_host キーで識別されるネイティブ ホストに接続しようとします (これについてはすぐに説明します)。次に、onMessage イベントのリスナーを登録します (このイベントは、ネイティブ ホストが Chrome 拡張機能にメッセージを送信したときにトリガーされます)。また、切断イベントのリスナーも登録します (たとえば、ネイティブ ホストが停止すると、このイベントがトリガーされます)。最後に、postMessage メソッドを使用してメッセージを送信します。

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

現在、ネイティブ ホストにも独自の manifest.json ファイルがあります。ネイティブ ホストの非常に単純な manifest.json ファイルは次のとおりです。

{
  "name": "com.dolby.native_messaging_host",
  "description": "Native messaging host",
  "path": "C:\\Users\\dbajg\\Desktop\\Native-messaging-host\\Debug\\Native-messaging-host.exe",
  "type": "stdio",
  "allowed_origins": [
    "chrome-extension://bjgnpdfhbcpjdfjoplajcmbleickphpg/"
  ]
}

ここで興味深い点がいくつかあります: name は、このネイティブ ホストが登録されているキーを識別します。パスは、ネイティブ ホスト実行可能ファイルへのフル パスです。通信のタイプ stdio は、通信に標準入出力を使用していることを意味します (現在サポートされているタイプのみ)。最後に、allowed_origins は、どの拡張機能がこのネイティブ ホストと通信できるかを指定します。そのため、拡張機能のキーを特定する必要があります。.

次の手順では、このネイティブ メッセージング ホストをレジストリ (Windows 用) に登録し、マニフェスト ファイルの場所を指定します。次のスクリーンショットは、Windows でこれを行う方法を説明しています (提供されたリンクを調べて、OSX および Linux でこれを行う方法を確認してください)。

ネイティブ メッセージング ホストのレジストリ エントリ (Windows OS のみ)

ネイティブ ホストのレジストリ エントリを追加したら、あとはネイティブ ホストを書き込むだけです。次の C++ コードは、標準入力からメッセージを読み取り、標準出力に応答を書き込む単純なネイティブ ホストを実装します (#STOP# メッセージを送信すると、ネイティブ ホストは終了します)。

#include <iostream>
#include <string>

int main(){
    std::string oneLine = "";

    while (1){
        unsigned int length = 0;

        //read the first four bytes (=> Length)
        /*for (int i = 0; i < 4; i++)
        {
            int read_char = getchar();
            length += read_char * (int) pow(2.0, i*8);
            std::string s = std::to_string((long long)read_char) + "\n";
            fwrite(s.c_str(), sizeof(char), s.size(), f);
            fflush(f);
        }*/

        //Neat way!
        for (int i = 0; i < 4; i++)
        {
            unsigned int read_char = getchar();
            length = length | (read_char << i*8);
        }

        //read the json-message
        std::string msg = "";
        for (int i = 0; i < length; i++)
        {
            msg += getchar();
        }

        std::string message = "{\"text\":\"This is a response message\"}";
        // Collect the length of the message
        unsigned int len = message.length();

        // Now we can output our message
        if (msg == "{\"text\":\"#STOP#\"}"){
            message = "{\"text\":\"EXITING...\"}";
            len = message.length();

            std::cout   << char(len>>0)
                        << char(len>>8)
                        << char(len>>16)
                        << char(len>>24);

            std::cout << message;
            break;
        }
        
        // return stdin message
        len = length;
        std::cout   << char(len>>0)
                    << char(len>>8)
                    << char(len>>16)
                    << char(len>>24);

        std::cout << msg << std::flush;

        // return response message
        // std::cout    << char(len>>0)
        //          << char(len>>8)
        //          << char(len>>16)
        //          << char(len>>24);
        //  
        // std::cout << message << std::flush;
    }
    
    return 0;
}

拡張によってネイティブ ホストに送信されるメッセージは、最初のバイトにメッセージのバイト数が格納されるように形成されます。したがって、ネイティブ ホストが最初に行う必要があるのは、最初の 4 バイトを読み取り、メッセージのサイズを計算することです。ここにある別の投稿でこれを行う方法を説明しました。

Chrome拡張機能によって送信されるメッセージのサイズを計算する方法

于 2014-10-27T08:55:56.550 に答える