Chrome Native Messaging API chrome.runtime.connectNative is not a function

11,412

You are not supposed to open main.html directly, but rather from Chrome's App Launcher at chrome://apps/

Share:
11,412
StealthRT
Author by

StealthRT

Updated on July 19, 2022

Comments

  • StealthRT
    StealthRT almost 2 years

    I am looking to manipulate the content page that's currently on the tab in Chrome and if this below can not do that then I need to find the way in order to do that!

    Hey all I am trying to get this new chrome extension working with my C# program to pass messages back and forth. I've seen a lot of demos of code on stackoverflow and that's mainly what I've been going by but it seems that all the examples are not working on my end.

    The issue I am having is I am getting the error of:

    Connecting to native messaging host com.google.chrome.example.echo
    Uncaught TypeError: chrome.runtime.connectNative is not a function
    

    enter image description here

    Whenever I try to "connect" to the port.

    Not sure what I am doing wrong since I have followed other tetorials on here and they all seem to state it works....

    The JS main.js:

    var port = null;
    var getKeys = function (obj) {
        var keys = [];
        for (var key in obj) {
            keys.push(key);
        }
        return keys;
    }
    function appendMessage(text) {
        document.getElementById('response').innerHTML += "<p>" + text + "</p>";
    }
    function updateUiState() {
        if (port) {
            document.getElementById('connect-button').style.display = 'none';
            document.getElementById('input-text').style.display = 'block';
            document.getElementById('send-message-button').style.display = 'block';
        } else {
            document.getElementById('connect-button').style.display = 'block';
            document.getElementById('input-text').style.display = 'none';
            document.getElementById('send-message-button').style.display = 'none';
        }
    }
    function sendNativeMessage() {
        message = { "text": document.getElementById('input-text').value };
        port.postMessage(message);
        appendMessage("Sent message: <b>" + JSON.stringify(message) + "</b>");
    }
    function onNativeMessage(message) {
        appendMessage("Received message: <b>" + JSON.stringify(message) + "</b>");
    }
    function onDisconnected() {
        appendMessage("Failed to connect: " + chrome.runtime.lastError.message);
        port = null;
        updateUiState();
    }
    function connect() {
        var hostName = "com.google.chrome.example.echo";
        appendMessage("Connecting to native messaging host <b>" + hostName + "</b>")
        console.log("Connecting to native messaging host " + hostName);
        port = chrome.runtime.connectNative(hostName);
        port.onMessage.addListener(onNativeMessage);
        port.onDisconnect.addListener(onDisconnected);
        updateUiState();
    }
    document.addEventListener('DOMContentLoaded', function () {
        document.getElementById('connect-button').addEventListener(
            'click', connect);
        document.getElementById('send-message-button').addEventListener(
            'click', sendNativeMessage);
        updateUiState();
    });
    

    The 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.",
      "app": {
        "launch": {
          "local_path": "main.html"
        }
      },
      "icons": {
        "128": "icon-128.png"
      },
      "permissions": [
        "nativeMessaging"
      ]
    }
    

    The Registry:

    REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.google.chrome.example.echo" /ve /t REG_SZ /d "%~dp0com.google.chrome.example.echo-win.json" /f
    

    C# code:

    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    
    namespace talkWithChromeCSharp
    {
        class Program
        {
            public static void Main(string[] args)
            {
                JObject data;
                while ((data = Read()) != null)
                {
                    var processed = ProcessMessage(data);
                    Write(processed);
                    if (processed == "exit")
                    {
                        return;
                    }
                }
            }
    
            public static string ProcessMessage(JObject data)
            {
                var message = data["message"].Value<string>();
                switch (message)
                {
                    case "test":
                        return "testing!";
                    case "exit":
                        return "exit";
                    default:
                        return "echo: " + message;
                }
            }
    
            public static JObject Read()
            {
                var stdin = Console.OpenStandardInput();
                var length = 0;
    
                var lengthBytes = new byte[4];
                stdin.Read(lengthBytes, 0, 4);
                length = BitConverter.ToInt32(lengthBytes, 0);
    
                var buffer = new char[length];
                using (var reader = new StreamReader(stdin))
                {
                    while (reader.Peek() >= 0)
                    {
                        reader.Read(buffer, 0, buffer.Length);
                    }
                }
    
                return (JObject)JsonConvert.DeserializeObject<JObject>(new string(buffer))["data"];
            }
    
            public static void Write(JToken data)
            {
                var json = new JObject();
                json["data"] = data;
    
                var bytes = System.Text.Encoding.UTF8.GetBytes(json.ToString(Formatting.None));
    
                var stdout = Console.OpenStandardOutput();
                stdout.WriteByte((byte)((bytes.Length >> 0) & 0xFF));
                stdout.WriteByte((byte)((bytes.Length >> 8) & 0xFF));
                stdout.WriteByte((byte)((bytes.Length >> 16) & 0xFF));
                stdout.WriteByte((byte)((bytes.Length >> 24) & 0xFF));
                stdout.Write(bytes, 0, bytes.Length);
                stdout.Flush();
            }
        }
    }
    

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

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

    HTML main.html:

    <!DOCTYPE html>
    
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="utf-8" />
        <script src='main.js'></script>
    </head>
    <body>
        <button id='connect-button'>Connect</button>
        <input id='input-text' type='text' />
        <button id='send-message-button'>Send</button>
        <div id='response'></div>
    </body>
    </html>
    

    My directory structure in Visual Studio:

    C:\Users\t||||||\Documents\Visual Studio 2012\Projects\talkWithChromeCSharp\talkWithChromeCSharp
       -APP
         |-icon-128.png
         |-main.html
         |-main.js
         |-manifest.json
       -bin
         |-Debug
            |-Newtonsoft.Json.dll
            |-talkWithChromeCSharp.exe
            |-etc etc...
         |-Release
       -obj
       -Properties
       -regs
         |-com.google.chrome.example.echo-win.json
         |-install_host.bat
         |-etc etc...
    

    After starting VS debug I install the plugin and load up the main.html file on the chrome browser and click the "connect" button. That's when I get that error.

    What am I missing?

    UPDATE

    That is the correct ID for it. I kept it that way since i'm guessing the "KEY" is what determines the ID.

    enter image description here enter image description here