I have a console application that needs to send a data to a Google Extension created by me also.
This is the manifest.json file:
{
"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
}
}
This is the background page:
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);
});
*/
}
This is the NativeMessage Host manifest file (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/"
]
}
The ID "laanpfddmhkpefimbmmbhojppeefdkbb" is the exact ID of the extension I saw after I installed it.
This code is in the Main method of Console application:
DataHelper.NativeMessage message = new DataHelper.NativeMessage("12345");
message.Send();
Finally, this is the NativeMessage class:
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);
}
}
}
I have the doubt when the host application is run. This is an application that is intended to be in execution all the time (finally, it will become a Windows Service).
To configure the host application, I have added this to the Windows registry:
REG ADD "HKLM\Software\Google\Chrome\NativeMessagingHosts\com.xxx.yyy" /ve /t REG_SZ /d "%~dp0com.xxx.yyy.json" /f
The process I followed is to add the Chrome extension and then execute the console application that immediately tries to send a message to the extension. I expect a log to be shown in console Window when the message is received.
EDIT:
Now, when I install Google Chrome extension, the host process is started, but I cannot send a message to the extension yet. I am using this piece of code:
DataHelper.NativeMessage message = new DataHelper.NativeMessage(String.Concat("{ command: Phone, parameter: ", e.Telefono, " }"));
message.Send();
But when the event is called in the extension, by mean of this listener:
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) });
});
Both msg.command and msg.parameter are undefined.