浏览器扩展和 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。