浏览器扩展和 windows 服务之间的通信
Communication between browser extension and windows service
我有一个浏览器扩展程序(适用于 chrome、Firefox、Edge),现在我想从扩展程序查询一些信息到 windows 服务,该服务位于 运行同一台机器。
我需要从扩展中传递一些字符串,windows 服务将处理这些字符串并 return 处理后的字符串。
我试过 WebAssembly 但它不适合我们的需要,因为它是编译代码而不是 运行 在后台。另外,服务中有一些windows特定的headers,webassembly不支持这些headers.
那么知道我们怎样才能做到这一点吗?
我将非常感谢 Whosebug 社区。
您可以使用本机消息传递(Chrome docs / MDN)
像这样创建一个可执行文件:
json_object process_string(std::string_view s) {
// Example code
std::string result(1000);
UINT sz;
HRESULT status = CallWindowsApi(s.data(), s.size(), result.data(), 1000, &sz);
if (FAILED(status)) {
return my_json_library::dict({{"err", my_json_library::integer(status)}});
}
return my_json_library::string(result.data(), sz);
}
int main() {
// Make sure stdin is open in binary mode to read the raw bytes of the size
_setmode(_fileno(stdin), O_BINARY);
_setmode(_fileno(stdout), O_BINARY);
while (true) {
// Message is prefixed with 4 byte size
std::uint32_t size;
{
char size_buf[4];
if (std::fread(size_buf, 4, 1, stdin) != 1) {
return std::feof(stdin) ? 0 : 1;
}
std::memcpy(&size, size_buf, 4);
}
// Followed by `size` bytes of JSON
json_object obj = my_json_library::read_from_FILE(stdin, size);
// Process the recieved message
if (!obj.is_string()) return 1;
std::string_view s = obj.as_string();
json_object result_json = process_string(s);
std::string result = result_json.stringify();
std::uint32_t result_size = result.size();
if (result_size > 1024 * 1024) {
// Chrome only allows 1MB messages to be recieved
// (Unsure if 1000*1000 (MB) or 1024*1024 (MiB))
// If you might run into this, make a message protocol to
// split messages into multiple 1MB chunks
}
// Sent messages are also prefixed by size
if (std::fwrite(&result_size, 4, 1, stdout) != 1) {
return 1;
}
// Followed by JSON data
if (std::fwrite(&result.data(), 1, result_size, stdout) != result_size) {
return 1;
}
}
}
使用相关注册表项注册相关清单文件的路径(可能使用安装程序安装可执行文件和清单文件 + 注册表项)
并且从chrome分机端调用比较简单:
let port = chrome.runtime.connectNative('com.my_company.my_application');
port.onMessage.addListener(function(msg) {
// Handle received message (what your executable writes)
if (typeof msg === 'string') {
// Success
} else {
// Error
const error_code = msg.err;
// ...
}
});
port.onDisconnect.addListener(function() {
// Handle crash (probably just reopen)
});
port.postMessage("string to transform");
// Can send any json message, but our executable only handles strings
或者每次都重新运行执行可执行文件(如果你使用这个,你可以删除可执行文件中的循环):
chrome.runtime.sendNativeMessage('com.my_company.my_application',
"string to transform",
function(msg) {
// Handle received message (what your executable writes)
});
或者,您可以 运行 某个任意(但不变)端口上的 HTTP 服务器执行此处理,并且您的 Web 扩展可以简单地 POST 数据到 `http://localhost:${port}`
。您可能应该允许在配置中更改 host/port。
我有一个浏览器扩展程序(适用于 chrome、Firefox、Edge),现在我想从扩展程序查询一些信息到 windows 服务,该服务位于 运行同一台机器。
我需要从扩展中传递一些字符串,windows 服务将处理这些字符串并 return 处理后的字符串。
我试过 WebAssembly 但它不适合我们的需要,因为它是编译代码而不是 运行 在后台。另外,服务中有一些windows特定的headers,webassembly不支持这些headers.
那么知道我们怎样才能做到这一点吗?
我将非常感谢 Whosebug 社区。
您可以使用本机消息传递(Chrome docs / MDN)
像这样创建一个可执行文件:
json_object process_string(std::string_view s) {
// Example code
std::string result(1000);
UINT sz;
HRESULT status = CallWindowsApi(s.data(), s.size(), result.data(), 1000, &sz);
if (FAILED(status)) {
return my_json_library::dict({{"err", my_json_library::integer(status)}});
}
return my_json_library::string(result.data(), sz);
}
int main() {
// Make sure stdin is open in binary mode to read the raw bytes of the size
_setmode(_fileno(stdin), O_BINARY);
_setmode(_fileno(stdout), O_BINARY);
while (true) {
// Message is prefixed with 4 byte size
std::uint32_t size;
{
char size_buf[4];
if (std::fread(size_buf, 4, 1, stdin) != 1) {
return std::feof(stdin) ? 0 : 1;
}
std::memcpy(&size, size_buf, 4);
}
// Followed by `size` bytes of JSON
json_object obj = my_json_library::read_from_FILE(stdin, size);
// Process the recieved message
if (!obj.is_string()) return 1;
std::string_view s = obj.as_string();
json_object result_json = process_string(s);
std::string result = result_json.stringify();
std::uint32_t result_size = result.size();
if (result_size > 1024 * 1024) {
// Chrome only allows 1MB messages to be recieved
// (Unsure if 1000*1000 (MB) or 1024*1024 (MiB))
// If you might run into this, make a message protocol to
// split messages into multiple 1MB chunks
}
// Sent messages are also prefixed by size
if (std::fwrite(&result_size, 4, 1, stdout) != 1) {
return 1;
}
// Followed by JSON data
if (std::fwrite(&result.data(), 1, result_size, stdout) != result_size) {
return 1;
}
}
}
使用相关注册表项注册相关清单文件的路径(可能使用安装程序安装可执行文件和清单文件 + 注册表项)
并且从chrome分机端调用比较简单:
let port = chrome.runtime.connectNative('com.my_company.my_application');
port.onMessage.addListener(function(msg) {
// Handle received message (what your executable writes)
if (typeof msg === 'string') {
// Success
} else {
// Error
const error_code = msg.err;
// ...
}
});
port.onDisconnect.addListener(function() {
// Handle crash (probably just reopen)
});
port.postMessage("string to transform");
// Can send any json message, but our executable only handles strings
或者每次都重新运行执行可执行文件(如果你使用这个,你可以删除可执行文件中的循环):
chrome.runtime.sendNativeMessage('com.my_company.my_application',
"string to transform",
function(msg) {
// Handle received message (what your executable writes)
});
或者,您可以 运行 某个任意(但不变)端口上的 HTTP 服务器执行此处理,并且您的 Web 扩展可以简单地 POST 数据到 `http://localhost:${port}`
。您可能应该允许在配置中更改 host/port。