title: Chrome Native Messaging API chrome.runtime.connectNative is not a function
body: <p><strong>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!</strong></p>
  
  <p>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.</p>
  
  <p>The issue I am having is I am getting the error of:</p>
  
  <pre><code>Connecting to native messaging host com.google.chrome.example.echo
  Uncaught TypeError: chrome.runtime.connectNative is not a function
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/ao4At.png" rel="noreferrer"><img src="https://i.stack.imgur.com/ao4At.png" alt="enter image description here"></a></p>
  
  <p>Whenever I try to "connect" to the port.</p>
  
  <p>Not sure what I am doing wrong since I have followed other tetorials on here and they all seem to state it works....</p>
  
  <p><strong>The JS main.js:</strong></p>
  
  <pre><code>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 += "&lt;p&gt;" + text + "&lt;/p&gt;";
  }
  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: &lt;b&gt;" + JSON.stringify(message) + "&lt;/b&gt;");
  }
  function onNativeMessage(message) {
      appendMessage("Received message: &lt;b&gt;" + JSON.stringify(message) + "&lt;/b&gt;");
  }
  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 &lt;b&gt;" + hostName + "&lt;/b&gt;")
      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();
  });
  </code></pre>
  
  <p><strong>The manifest.json:</strong></p>
  
  <pre><code>{
    // 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"
    ]
  }
  </code></pre>
  
  <p>The Registry:</p>
  
  <pre><code>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
  </code></pre>
  
  <p><strong>C# code:</strong></p>
  
  <pre><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&lt;string&gt;();
              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() &gt;= 0)
                  {
                      reader.Read(buffer, 0, buffer.Length);
                  }
              }
  
              return (JObject)JsonConvert.DeserializeObject&lt;JObject&gt;(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 &gt;&gt; 0) &amp; 0xFF));
              stdout.WriteByte((byte)((bytes.Length &gt;&gt; 8) &amp; 0xFF));
              stdout.WriteByte((byte)((bytes.Length &gt;&gt; 16) &amp; 0xFF));
              stdout.WriteByte((byte)((bytes.Length &gt;&gt; 24) &amp; 0xFF));
              stdout.Write(bytes, 0, bytes.Length);
              stdout.Flush();
          }
      }
  }
  </code></pre>
  
  <p><strong>com.google.chrome.example.echo-win.json file:</strong></p>
  
  <pre><code>{
    "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/"
    ]
  }
  </code></pre>
  
  <p><strong>HTML main.html:</strong></p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  
  &lt;html lang="en" xmlns="http://www.w3.org/1999/xhtml"&gt;
  &lt;head&gt;
      &lt;meta charset="utf-8" /&gt;
      &lt;script src='main.js'&gt;&lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
      &lt;button id='connect-button'&gt;Connect&lt;/button&gt;
      &lt;input id='input-text' type='text' /&gt;
      &lt;button id='send-message-button'&gt;Send&lt;/button&gt;
      &lt;div id='response'&gt;&lt;/div&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>My directory structure in Visual Studio:</p>
  
  <pre><code>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...
  </code></pre>
  
  <p>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.</p>
  
  <p>What am I missing?</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>That is the correct ID for it. I kept it that way since i'm guessing the "KEY" is what determines the ID.</p>
  
  <p><a href="https://i.stack.imgur.com/FldwF.png" rel="noreferrer"><img src="https://i.stack.imgur.com/FldwF.png" alt="enter image description here"></a>
  <a href="https://i.stack.imgur.com/zcZpR.png" rel="noreferrer"><img src="https://i.stack.imgur.com/zcZpR.png" alt="enter image description here"></a></p>