Native messaging from chrome extension to native host written in C#
Asked Answered
P

1

4

I'm trying to receive a message from my chrome extension via native messaging. The popup.html console indicates that the message is being sent, but my host is not receiving it for some reason. I can see that the host native.exe is being launched in task manager, but the host is not receive the sent data.

popup.js

document.addEventListener('DOMContentLoaded', function() {
    var downloadButton= document.getElementById('Button');
    downloadButton.addEventListener('click', function () {
        chrome.tabs.query({currentWindow: true, active: true}, function (tabs) {
            chrome.tabs.executeScript(tabs[0].id, {file: "myScript.js"}, function (data) {
                sendNativeMessage(data[0]);
            });
        });
    });
});

function sendNativeMessage(msg) {
    var hostName = "com.google.example";

    console.log("Connecting to host: " + hostName);
    port = chrome.runtime.connectNative(hostName);

    message = {"text": msg};
    port.postMessage(message);

    console.log("Sent message: " + JSON.stringify(message));
}

Now, when I send the message from my Chrome Extension, I can see the console log for popup.html and the message is correct.

I tried to test everything by using some code that someone claimed to have worked, from Native Messaging Chrome. Specifically, I have

native.exe

    static void Main(string[] args) {
        while (OpenStandardStreamIn() != null || OpenStandardStreamIn() != "")
        {
            Console.WriteLine(OpenStandardStreamIn());
        }
    }

    private static string OpenStandardStreamIn()
    {
        //Read first four bytes for length information
        System.IO.Stream stdin = Console.OpenStandardInput();
        int length = 0;
        byte[] bytes = new byte[4];
        stdin.Read(bytes, 0, 4);
        length = System.BitConverter.ToInt32(bytes, 0);

        string input = "";
        for (int i = 0; i < length; i++)
            input += (char)stdin.ReadByte();

        return input;
    }

I'm still trying to wrap my head around nativeMessaging, but since I can see the message being sent via the console logs, I have to assume the error is with my .exe. I have created the registry keys, HKCU, and created the host's manifest.json file. Since the extension is launching the .exe, I'm pretty sure all of that is working fine as well.

If anyone could provide some assistance with this, that would be much appreciated. Thanks!


EDIT: After changing absolutely nothing, I cannot get my native.exe to launch anymore from my extension. In an effort to fix this, I tried rewriting my sender to not open a port:

...
chrome.tabs.executeScript(tabs[0].id, {file: "myScript.js"}, function (data) {
    chrome.runtime.sendNativeMessage('com.google.example', {"text":data[0]}, function(response) {
        if (chrome.runtime.lastError)
            console.log("ERROR");
        } else {
            console.log("Response: " + response);
        }
    });
});
...

This doesn't work at all either. I have no idea what I'm doing wrong, or why my host .exe stopped launching when I sent a message from my extension.


EDIT #2

Good news!

I deleted my registry key and then added it again, this time into the Local Machine registry (i.e. HKLM). Again, I used the code from Native Messaging Chrome to send and receive from my host. Now, when I look at my extension's log, I can see the correct response from my host. I am using the "no-port" method by simply calling chrome.runtime.sendNativeMessage(...), which is fine for my purposes. Unfortunately, I am not receiving the message FROM the extension TO the host. Also, my host.exe never exits, even after the message has been received. I'm not sure why, but if anyone can help out, I would appreciate it.

In my host, I'm attempting to write the incoming message to a file just to test that I'm getting the message:

System.IO.File.WriteAllText(@"path_to_file.txt", OpenStandardStreamIn());

Note: The message that I'm passing FROM the extension TO the host is around 250KB (it varies from message to message).

The problem is:

  1. Nothing is written to the file. It's completely blank.
  2. The file takes a long time to create (~4 seconds).
  3. My host.exe instance never terminates. It's still running (I can view it in the task manager).
Pivoting answered 25/12, 2014 at 3:5 Comment(3)
Have you tried logging chrome.runtime.lastError.message?Thrall
@Thrall Yes. I get a specified native messaging host not found error. I've created my key in the HKCU registry and pointed it to my host-manifest.json, which I've stored in the same directory as my host.exe just for good measure. Also, yesterday, when I sent a message from my extension, an instance of host.exe was showing up in the taskmgr, so I'm not sure why it broke.Pivoting
@Thrall I fixed the host not found error, but now I'm stuck on actually receiving the message from the Chrome extension. I'm also trying to figure out why my host.exe is not terminating after the file is created. See Edit #2.Pivoting
P
2

In order to get my extension working, I followed the following steps:

  1. I deleted my registry key and then re-added it in my HKLM registry.
  2. Although unnecessary,host.exe really only needed to receive one message from the extension, so I changed my previous "open port" messaging to a "no port" message, i.e.

    chrome.runtime.sendNativeMessage(...);

  3. Importantly, when I changed the text I was sending from {"text":data[0]} to a simple string {"text":"Hello from Chrome!"}, everything began working smoothly. data[0] was a string of about 250KB, which should definitely be an acceptable message size according to the developer's site. However, I have created a different question for this problem, as I was able to solve the general message sending and receiving problem I was experiencing.

Pivoting answered 26/12, 2014 at 6:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.