Pytanie Host natywny w języku C # dzięki przeglądarce Native Messaging w Chrome


Kilka godzin spędziłem na badaniu, jak uzyskać natywne komunikaty w Chrome współpracujące z hostem w języku C #. Koncepcyjnie było to dość proste, ale było kilka przeszkód, które rozwiązałem z pomocą (częściowo) z tych innych pytań:

Natywna aplikacja Messaging Chrome
Natywne wiadomości z rozszerzenia chrome na rodzimy host napisany w C #
Bardzo wolno przesyłać "dużą" ilość danych z rozszerzenia Chrome na hosta (napisane w języku C #)

Moje rozwiązanie jest zamieszczone poniżej.


21
2018-06-17 01:03


pochodzenie




Odpowiedzi:


Zakładając, że manifest jest poprawnie skonfigurowany, oto pełny przykład rozmawiania z hostem C # za pomocą metody "port":

using System;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace NativeMessagingHost
{
   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["text"].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));
      }

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

Jeśli nie musisz aktywnie komunikować się z hostem, użyj runtime.sendNativeMessage będzie działać dobrze. Aby zapobiec zawieszeniu się hosta, po prostu usuń while pętli i wykonaj jednokrotnie odczyt / zapis.

Aby to przetestować, użyłem przykładowego projektu dostarczonego przez Google tutaj: https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/docs/examples/api/nativeMessaging

Uwaga: Używam Json.NET, aby uprościć proces serializacji / odszyfrowania json.

Mam nadzieję, że jest to pomocne dla kogoś!


27
2018-06-17 01:03



Szukam tego dla Javy, ale nigdzie nie mogę znaleźć: / - farukdgn
@farukdgn Konkretnie, co jest trudne do znalezienia? Implementacja Java powinna być dość podobna. - itslittlejohn
Tak, dziękuję, to doskonały początek! - shaune
Gdzie jest połączenie? próbowałem go uruchomić, a rozszerzenie daje mi "Natywny host wyszedł." - ArielB
Podczas inicjowania połączenia ze skryptu w tle (rozszerzenie chrome) - połączenie nie powiedzie się, mimo że plik host.exe zostanie otwarty. "Nie można się połączyć: Błąd podczas komunikacji z natywnym hostem przesyłania komunikatów". Według Google połączyć dzieje się tak z powodu błędnej deklaracji serializacji / rozmiaru. Jakaś wskazówka? - David D.