C#原生主机与Chrome本地消息传递

31
2个回答

42
假设清单已正确设置,以下是使用“端口”方法与C#主机通信的完整示例:

假设清单已正确设置,以下是使用“端口”方法与C#主机通信的完整示例:

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

如果您不需要主动与主机通信,使用runtime.sendNativeMessage即可。为了防止主机挂起,只需删除while循环并进行一次读/写操作。

为了测试这个功能,我使用了Google提供的示例项目:https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/docs/examples/api/nativeMessaging

注意:我使用Json.NET来简化JSON序列化/反序列化过程。

希望这对某些人有所帮助!


我正在寻找Java的相关内容,但是无论去哪里都找不到 :/ - omerfarukdogan
@farukdgn 具体来说,你发现了什么难以找到的东西?Java 实现应该是相当相似的。 - itslittlejohn
1
连接在哪里?我尝试运行它,但扩展程序显示“本机主机已退出”。 - ArielB
1
当从后台脚本(Chrome扩展程序)初始化连接时,即使host.exe打开,连接仍会失败。 "连接失败:与本机消息主机通信时出错。" 根据Google 链接的说法,这是由于错误的序列化/大小声明引起的。有任何线索吗? - David D.
2
为什么不直接创建一个StreamWriter并写入string.Length和string呢?为什么必须使用WriteByte来写入int? - Robert Chitoiu
显示剩余2条评论

0

您也可以使用常规的http通信。并使用fetch或其他js api发送消息。主机应用程序将是在本地主机上运行的常规Web API项目。您还需要在Web应用程序中启用CORS策略。对于某些情况来说可能有点过度,而且可能不太快。但对于大多数开发人员来说更透明,并且在我的项目中表现出色。


这并没有回答问题。一旦您拥有足够的声望,您将能够评论任何帖子;相反,提供不需要询问者澄清的答案。- 来自审核 - possum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接