C ++ Embedded Chrome Host Cannot Communicate With Chrome

I am trying to implement a Chrome extension using runtime.connectNative and postMessage . I follow the Chrome documentation, downloaded an example of my own posts, and changed my own application to use C ++.

However, the native application cannot receive the message from the Chrome extension.

Meanwhile, when a native application using the printf function writes a message to the chrome extension, the extension cannot receive a message that is simply displayed on the console.

Any ideas how to solve the problem?

+7
c ++ google-chrome-extension chrome-native-messaging
source share
2 answers

You did not provide much information about what you actually tried, so I will do my best to explain the steps necessary to implement the Chrome Extension host, Native Messaging and establish a connection between them. (Please see the following link for more information about Chrome Native Messaging: Chrome Personal Account .

CHROMIUM EXPANSION

First, we need to configure the Chrome extension. Since this will be a very simple extension, we only need the manifest.json file (note that this is an extension manifest file - your own host will also have its own manifest file) and background.js javascript.

The following is an example manifest.json file:

 { "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 } 

It is important that the implementation will be provided in background.js, the minimum version of Chrome is 29, and HTTP and HTTPS support is supported.

Further, background.js has the following content:

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

The code itself is pretty straightforward - we are trying to connect to our own node identified using the com.dolby.native_messaging_host key (I will come to this in a minute). Then we register a listener for the onMessage event (this event is fired when the host sends a message to the chrome extension). We also register a listener for the disconnect event (for example, when the local host dies, this event will be fired). And finally, we send the message using the postMessage method.

NATIVE MESSAGING HOST

Now the native host also has its own manifest.json file. A very simple manifest.json file for your own host is as follows:

 { "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/" ] } 

A few interesting things here: name identifies the key under which this own host is registered. Path - The full path to the executable executable. The stdio communication type means that we use standard input / output for communication (only the type is supported). And finally, allowed_origins will indicate which extensions can communicate with this own host - so you need to find out what is your extension key. .

The next step is to register this Native Messaging host in the registry (for Windows) and specify the location in its manifest file. The following screenshots explain how to do this for Windows (check out the link to find out how to do this on OSX and Linux):

Registry entry for native messaging host (Windows OS only)

After you have added an entry to the registry for your own host, you just have to write your own host. The following C ++ code implements a simple native host that reads messages from standard input and writes the response to standard output (when you send the message # STOP #, on which the native host is called):

 #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; } len = length; std::cout << char(len>>0) << char(len>>8) << char(len>>16) << char(len>>24); std::cout << msg << std::flush; } return 0; } 

Messages sent by the extension to its own host are formed in such a way that the first byte stores the number of bytes in the message. So, the first thing the main host should do is read the first 4 bytes and calculate the size of the message. I explained how to do this in another post, which can be found here:

How to calculate the size of a message sent using the chrome extension

+17
source share

For future Google people, here's how I do it:

Style C

Reading

 char bInLen[4]; read(0, bInLen, 4); // 0 is stdin unsigned int inLen = *(unsigned int *)bInLen; char *inMsg = (char *)malloc(inLen); read(0, inMsg, inLen); inMsg[inLen] = '\0'; ... free(inMsg); 

Record

 char *outMsg = "{\"text\":\"This is a response message\"}"; unsigned int outLen = strlen(outMsg); char *bOutLen = (char *)&outLen; write(1, bOutLen, 4); // 1 is stdout write(1, outMsg, outLen); fflush(stdout); 

C ++ style

Reading

 char bInLen[4]; cin.read(bInLen, 4); unsigned int inLen = *reinterpret_cast<unsigned int *>(bInLen); char *inMsg = new char[inLen]; cin.read(inMsg, inLen); string inStr(inMsg); // if you have managed types, use them! delete[] inMsg; 

Record

 string outMsg = "{\"text\":\"This is a response message\"}"; unsigned int outLen = outMsg.length(); char *bOutLen = reinterpret_cast<char *>(&outLen); cout.write(bOutLen, 4); cout << outMsg << flush; 
+4
source share

All Articles