简体   繁体   English

浏览器扩展与 windows 服务之间的通信

[英]Communication between browser extension and windows service

I have a browser extension(For chrome, Firefox, Edge) and now I want to query some info from the extension to the windows service which is running on the same machine.我有一个浏览器扩展(对于 chrome,Firefox,Edge),现在我想从扩展中查询一些信息,该扩展是在同一台机器上运行的 windows 服务。

I need to pass some strings from the extension and the windows service will process these strings and return the processed strings.我需要从扩展中传递一些字符串,windows 服务将处理这些字符串并返回处理后的字符串。

I have tried WebAssembly but it does not suit our need because it is compiled code and not running in the background.我已经尝试过WebAssembly ,但它不适合我们的需要,因为它是编译后的代码,而不是在后台运行。 Also, there are some windows specific headers in the service, and web assembly does not support these headers.此外,服务中有一些 windows 特定的头文件,web 组件不支持这些头文件。

so any idea how can we achieve that?所以知道我们怎样才能做到这一点吗?

I will be very thankful to the StackOverflow community.我将非常感谢 StackOverflow 社区。

You can use native messaging ( Chrome docs / MDN )您可以使用本机消息传递( Chrome 文档/ MDN

Create an executable like this:像这样创建一个可执行文件:

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;
        }
    }
}

Register the path of the relevent manifest file using the relevant registry key (probably using an installer to install both the executable and the manifest file + registry key)使用相关注册表键注册相关清单文件的路径(可能使用安装程序来安装可执行文件和清单文件+注册表键)

And it is relatively simple to call from the chrome extension side:而且从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

Or re-running the executable every time (you can remove the loop in the executable if you use this):或者每次都重新运行可执行文件(如果你使用这个,你可以删除可执行文件中的循环):

chrome.runtime.sendNativeMessage('com.my_company.my_application',
  "string to transform",
  function(msg) {
    // Handle received message (what your executable writes)
  });

Alternatively, you can run a HTTP server on some arbitrary (but unchanging) port which does this processing, and your web extension can simply POST data to `http://localhost:${port}` .或者,您可以在执行此处理的任意(但不变)端口上运行 HTTP 服务器,并且您的 web 扩展程序可以简单地将数据发布到`http://localhost:${port}` You should probably allow the host/port to be changed in the config.您可能应该允许在配置中更改主机/端口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM