使用NativeMessage

时间:2016-08-29 20:45:54

标签: c# google-chrome-extension google-chrome-devtools chrome-native-messaging

我有一个控制台应用程序需要将数据发送到我创建的Google扩展程序。

这是manifest.json文件:

{
  "manifest_version": 2,

  "name": "Busca Cliente Lipigas",
  "description": "Esta extensión permite recibir un número de teléfono desde el servidor DDE y realizar la búsqueda del cliente en la página Web de Lipigas.",
  "version": "1.0",

  "permissions": [
    "tabs",
    "nativeMessaging"
  ],

  "icons" : { "16": "img/icon16.png",
              "48": "img/icon48.png",
              "128": "img/icon128.png" },

  "background": {
    "scripts": ["main.js"],
    "persistent": false
    }

}

这是背景页面:

var clientSearchPage;
var clientEditPage;

/**
 * Listens for the app launching then creates the window
 *
 * @see https://developer.chrome.com/apps/app_runtime
 * @see https://developer.chrome.com/apps/app_window
 */

console.log('Extensión iniciada.');
var port = chrome.runtime.connectNative('com.xxx.yyy');
console.log('Escuchando en el puerto ' + port);
port.onMessage.addListener(function (msg) {
    console.log("Se recibió el comando " + msg);

    port.postMessage({ status: processCommand(request.comando) });
});

// event logger
var log = (function () {
    var logLines = [];
    var logListener = null;

    var output = function (str) {
        if (str.length > 0 && str.charAt(str.length - 1) != '\n') {
            str += '\n'
        }
        logLines.push(str);
        if (logListener) {
            logListener(str);
        }
    };

    var addListener = function (listener) {
        logListener = listener;
        // let's call the new listener with all the old log lines
        for (var i = 0; i < logLines.length; i++) {
            logListener(logLines[i]);
        }
    };

    return { output: output, addListener: addListener };
})();

function processCommand(cmd) {
    var cmd = line.split(/\s+/);
    try {
        switch (cmd[0]) {
            case 'Phone':
                setPhone(cmd[1]);
                return '+OK-Phone';
                break;
            case 'SetClientPage':
                clientEditPage = cmd[1];
                return '+OK-SetClientPage';
                break;
            case 'SetSearchPage':
                clientSearchPage = cmd[1];
                return '+OK-SetSearchPage';
                break;
            default:
                return '+ERR-Comando No Encontrado';
        }
        //tcpConnection.sendMessage(Commands.run(cmd[0], cmd.slice(1)));
    } catch (ex) {
        return '+ERR-Comando No Procesado'
    }
}

function setPhone(phone) {
    log.output('Se recibió llamada desde el teléfono ' + phone + '. Refrescando página.');
    /*
    chrome.runtime.sendMessage({ phone: phone }, function (response) {
        // los valores de respuesta válidos son:
        //   -1: búsqueda en página nueva
        //   -2: búsqueda en página existente
        var tipoBusqueda = '';
        switch (response) {
            case '-1':
                tipoBusqueda = 'nueva'; break;
            case '-2':
                tipoBusqueda = 'existente'; break;
        }
        if (tipoBusqueda == '')
            console.log('No hubo comunicación con la extensión cliente.');
        else
            console.log('Cliente con el teléfono ' + phone + ' fue buscado en una página ' + tipoBusqueda + '.');
    });
    */
    /*
    chrome.tabs.query({
    }, function (tabs) {
        var tabURL = tabs[0].url;
        console.log(tabURL);
    });
    */
}

这是NativeMessage主机清单文件(com.xxx.yyy.json):

{
  "name": "com.xxx.yyy",
  "description": "Native Messaging API para el Servicio Windows",
  "path": "ConsolaDDE.exe",
  "type": "stdio",
  "allowed_origins": [
    "chrome-extension://laanpfddmhkpefimbmmbhojppeefdkbb/"
  ]
}

ID&#34; laanpfddmhkpefimbmmbhojppeefdkbb&#34;是我安装后看到的扩展名的确切ID。

此代码位于Console应用程序的Main方法中:

            DataHelper.NativeMessage message = new DataHelper.NativeMessage("12345");
            message.Send();

最后,这是NativeMessage类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace DataHelper
{
    public class NativeMessage
    {
        public int Length;
        public byte[] Data;

        public string UTF8()
        {
            return Encoding.UTF8.GetString(Data);
        }

        public NativeMessage(int length, byte[] data)
        {
            Length = length;
            Data = data;
        }

        public NativeMessage(string utf8)
        {
            byte[] data = Encoding.UTF8.GetBytes(utf8);

            Length = data.Length;
            Data = data;
        }

        public string GetData()
        {
            return Encoding.UTF8.GetString(Data);
        }

        public NativeMessage Send(Stream s = null)
        {
            if (s == null)
            {
                s = Console.OpenStandardOutput();
            }

            s.Write(BitConverter.GetBytes(Length), 0, sizeof(int));
            s.Write(Data, 0, Length);
            s.Flush();

            return this;
        }

        public static NativeMessage Read(Stream s = null)
        {
            if (s == null)
            {
                s = Console.OpenStandardInput();
            }

            byte[] i = new byte[sizeof(int)];
            s.Read(i, 0, sizeof(int));
            int len = BitConverter.ToInt32(i, 0);

            byte[] data = new byte[len];
            s.Read(data, 0, len);

            return new NativeMessage(len, data);
        }
    }
}

运行主机应用程序时我有疑问。这是一个旨在一直执行的应用程序(最后,它将成为Windows服务)。

要配置主机应用程序,我已将其添加到Windows注册表中:

REG ADD "HKLM\Software\Google\Chrome\NativeMessagingHosts\com.xxx.yyy" /ve /t REG_SZ /d "%~dp0com.xxx.yyy.json" /f

我遵循的流程是添加Chrome扩展程序,然后执行立即尝试向扩展程序发送邮件的控制台应用程序。我希望收到消息后,在控制台窗口中显示日志。

编辑:

现在,当我安装Google Chrome扩展程序时,主机进程已启动,但我还无法向扩展程序发送消息。我正在使用这段代码:

        DataHelper.NativeMessage message = new DataHelper.NativeMessage(String.Concat("{ command: Phone, parameter: ", e.Telefono, " }"));
        message.Send();

但是当在扩展中调用事件时,通过这个监听器:

port.onMessage.addListener(function (msg) {
    console.log("Se recibió el comando " + msg.command + ' con el parámetro ' + msg.parameter);

    port.postMessage({ status: processCommand(msg.command + ' ' + msg.parameter) });
});

msg.command和msg.parameter都是未定义的。

1 个答案:

答案 0 :(得分:0)

请注意Native Messaging的机制,通过扩展程序启动通讯。 Chrome是在单独的进程中启动主机,然后他们可以使用stdin和stdout相互通信。

乍一看,您的问题可能是您没有在扩展端启动通信,这意味着在port.postMessage()处理程序之外调用onMessage