Kha*_*ech 7 macos chrome-native-messaging xamarin.forms
我尝试重新创建示例以使用 chrome 扩展程序连接到我的 Xamarin Mac 应用程序,我将用作所有其他浏览器的主干,但它没有使用以下错误:
与本机消息传递主机通信时出错。
文档在纸面上看起来很简单,但在现实生活中却没有那么简单。
这是我的阅读和聆听功能(那里有很好的例子,https : //github.com/anewtonlevey/NativeMessaging):
    public void Listen()
    {
        JObject data;
        while ((data = Read()) != null)
        {
            ProcessReceivedMessage(data);
        }
    }
    private JObject Read()
    {
        try
        {
            Stream stdin = Console.OpenStandardInput();
            byte[] lengthBytes = new byte[4];
            stdin.Read(lengthBytes, 0, 4);
            var buffer = new char[BitConverter.ToInt32(lengthBytes, 0)];
            using (var reader = new StreamReader(stdin)) while (reader.Peek() >= 0) reader.Read(buffer, 0, buffer.Length);
            return JsonConvert.DeserializeObject<JObject>(new string(buffer));
        }
        catch (Exception e)
        {
            Console.WriteLine("Read error: {0}", e);
            return null;
        }
    }
在我的 main 函数中,我使用以下命令调用它们:
        host = new ExtendedHost();
        host.Listen();
请注意,我正在为 macOS 应用程序使用来自 Xamarin 表单的本机消息传递,从我的角度来看,这可能是字节序,如以下文档所示:
与本机消息传递主机通信时出错:
https://developer.chrome.com/extensions/nativeMessaging#native-messaging-host-protocol
当我从 Web 扩展发送消息时,我的 C# 应用程序的另一个窗口似乎想要打开,这意味着错误似乎发生在读取步骤。
非常感谢帮助。
谢谢。
编辑:
我建议使用字节序,因为文档表明响应也应该是正确的,否则会使整个过程损坏,如本机消息传递协议文档中所建议的那样,但这肯定不是问题,因为我仍然应该能够解析数据发送:
https://developer.chrome.com/apps/nativeMessaging#native-messaging-host-protocol
我看到响应与它有关,并且用于发送消息的函数(因为有人建议响应中的错误可能导致整体错误)会导致问题,或者 Console.StandardInput() 不会按照建议工作,但我也不这么认为。
我的想法是,当我使用ps aux | 时,尝试附加到正在运行的应用程序会导致问题。grep app_name,并将路径放在主机文件中。
这是协议中的提及:
本机消息传递协议 Chrome 在单独的进程中启动每个本机消息传递主机,并使用标准输入 (stdin) 和标准输出 (stdout) 与其进行通信。
我还在另一篇文章中看到了 Xan 的这个答案,即本机消息传递无法附加到正在运行的进程,Chrome 应该启动该进程:
不要忘记我在调试模式下在 Xamarin macOS 中使用本机消息传递 API,并且我的应用程序是 macOS 应用程序。
欢迎提供有关该主题的更多信息,例如:
当然,如果这是您认为导致问题的原因。
提前致谢!
编辑:
将输出发送到 stderr 时,出现以下错误:
读取错误:System.NotSupportedException:Stream 不支持在 System.IO.FileStream.Read 读取(System.Byte[] 数组,System.Int32 偏移量,System.Int32 计数)[0x0002e] 在 /Library/Frameworks/Xamarin.Mac .framework/Versions/Current/src/Xamarin.Mac/mcs/class/corlib/System.IO/FileStream.cs:493
难道是 Console.OpenStandardInput 不能跨平台工作?如果是这样,解析标准输入的另一种方法是什么,因为我看到管道可以工作,但我不确定它们是否可以跨平台部署。
阅读时我没有任何错误或输出,只有在应用程序启动时出现上述错误。对我来说,OpenStandardInput 似乎是罪魁祸首。
任何想法表示赞赏!谢谢
基本上,从扩展发送的前 32 位对应于本机顺序的消息长度。
由于前 32 位是 int 类型,并且我尝试解析 JSON 对象,因此与本机消息传递主机通信时出现错误。该文档提到该问题存在于损坏的本机消息传递协议中。
最糟糕的是,我在 Python 示例中看到了它,但认为这是由执行此操作的程序员实现的。
我在 Stack Overflow 上偶然发现了这个线程,它帮助确认了(Chrome 应用程序无法与 Windows 上的本机主机通信)。
要以更详细的方式调试 Chrome,请在命令行中使用--enable-logging=stderr --v=1启动 Chrome,所有 stderr 都将在那里输出。
文档中提到了这一点,但这里和那里使用 C# 找到的示例不包括它们。
如果我有时间,我将通过编辑此答案来确认这是问题所在,并提供使其在 Visual Studio for macOS 上运行的代码。
几天前我设法让它工作。我修改了代码,使其无需 while 循环即可工作,因为 StreamReader 读取 stdin 直至结束,因此不会请求 while 循环(这导致我之前的代码挂起)。SendMessage 方法也与其他示例中看到的不同。行数更少,而且效果很好。
我的工作示例:
public void Listen()
{
    JObject data;
    //while ((data = Read()) != null)
    //{
    //    ProcessReceivedMessage(data);
    //}
    if((data = Read()) != null)
    {
        string message = ProcessReceivedMessage(data);
        SendMessage(message);
    }
}
    private JObject Read()
    {
        Stream stdin = Console.OpenStandardInput();
        byte[] lengthBytes = new byte[4];
        stdin.Read(lengthBytes, 0, lengthBytes.Length);
        char[] buffer = new char[BitConverter.ToInt32(lengthBytes, 0)];
        var reader = new StreamReader(stdin);
        //int messageLength =
        reader.Read(buffer, 0, buffer.Length);
        return JsonConvert.DeserializeObject<JObject>(new string(buffer));
    }
    public void SendMessage(JToken data)
    {
        var bytes = Encoding.UTF8.GetBytes(data.ToString(Formatting.None));
        var lengthBytes = BitConverter.GetBytes(bytes.Length);
        var stdout = Console.OpenStandardOutput();
        stdout.Write(lengthBytes, 0, 4);
        stdout.Write(bytes, 0, bytes.Length);
        stdout.Flush();
    }