Chrome native messaging on windows

Chriksz picture Chriksz · Feb 22, 2014 · Viewed 13.5k times · Source

I think it was already waiting for answer, but not sure: Native app does not work in Chrome extension
On Linux, it works fine, but on Windows 7 and 8 I always get an error "Specified native messaging host not found".

This is my registry (I've already tried with double backslash and with HKEY_LOCAL_MACHINE):

REG ADD HKEY_CURRENT_USER\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.google.chrome.example.echo /ve /d C:\Users\Chriss\Desktop\nativeMessaging\host\com.google.chrome.example.echo-win.json


manifest.json:

{
    // Extension ID: knldjmfmopnpolahpmmgbagdohdnhkik
    "key":"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcBHwzDvyBQ6bDppkIs9MP4ksKqCMyXQ/A52JivHZKh4YO/9vJsT3oaYhSpDCE9RPocOEQvwsHsFReW2nUEc6OLLyoCFFxIb7KkLGsmfakkut/fFdNJYh0xOTbSN8YvLWcqph09XAY2Y/f0AL7vfO1cuCqtkMt8hFrBGWxDdf9CQIDAQAB",
    "name": "Native Messaging Example",
    "version": "1.0",
    "manifest_version": 2,
    "description": "Send a message to a native application.",
    "browser_action": {
    "default_title": "Test Extension",
    "default_popup": "main.html"
    },
    "icons": {
    "128": "icon-128.png"
    },
    "permissions": [
    "nativeMessaging"
    ]
}


com.google.chrome.example.echo-win.json:

{
    "name": "com.google.chrome.example.echo",
    "description": "Chrome Native Messaging API Example Host",
    "path": "C:\Users\Chriss\Desktop\nativeMessaging\host\native-messaging-example-host.exe",
    "type": "stdio",
    "allowed_origins": [
    "chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/"
    ]
}


native-messaging-example-host.exe:

int main(int argc, char* argv[]) {
    // Define our message
    std::string message = "{\"text\": \"This is a response message\"}";
    // Collect the length of the message
    unsigned int len = message.length();
    // We need to send the 4 bytes of length information
    std::cout 
        << char(((len >> 0) & 0xFF))
        << char(((len >> 8) & 0xFF))
        << char(((len >> 16) & 0xFF))
        << char(((len >> 24) & 0xFF));
    // Now we can output our message
    std::cout << message;
    return 0;
}


JS snippet(it is from http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/api/nativeMessaging/app/main.js?revision=228976 ):

function connect() {
    var hostName = "com.google.chrome.example.echo";
    appendMessage("Connecting to native messaging host <b>" + hostName + "</b>")
    port = chrome.runtime.connectNative(hostName);
    port.onMessage.addListener(onNativeMessage);
    port.onDisconnect.addListener(onDisconnected);
    updateUiState();
}

I cannot find out what is the problem. Where is my fault?

update
After monitoring the registries with Procces Monitor. I found that the chrome.exe searches for the key in the 64bit keys. Now as I can see there's no missing relevant registry key, but I still get the error.

Answer

Yehuda picture Yehuda · Feb 24, 2014

I also struggled with this issue on Windows, but was able to get it work. Try the following:

Regarding the registry (mine on the HKLM, but HKCU should be OK) you should use double backslash. Here is my .reg file:

[HKEY_LOCAL_MACHINE\SOFTWARE\Google\Chrome\NativeMessagingHosts\tcchrome.native.handler]
@="G:\\\ExtChrome\\\Extension\\\Native\\\manifest.json"
  1. Keep the name of the native process with lowercase letters and only 3 parts - meaning com.google.chrome. It sounds weird but this is how it is working for me...
  2. Put the exe and the manifest in the same folder, so that path will be "native-messaging-example-host.exe" - In this case I am sure because I tested it.

Here is my manifest for example:

{
    "name": "chrome.native.handler",
    "description": "BlaBla helper process",
    "path": "chrome.native.handler.exe",
    "type": "stdio",
    "allowed_origins": [
    "chrome-extension://eoknpfoeckmeidbmbfoklejkppcnlfdm/"
    ]
}

BTW, you are not handling the response right. You are supposed to send the message length in "native byte order" - what you are doing will not work for larger messages. Instead you can do something like:

cout.write((char*)&resSize, 4);
cout.write(responseBuf, resSize);

Hope this helps