【问题标题】:Calling a C dll through chrome browser extension通过 chrome 浏览器扩展调用 C dll
【发布时间】:2016-02-09 03:53:59
【问题描述】:

我想通过 chrome 扩展程序通过 winscard.dll 访问智能卡。

我是 Chrome 扩展程序开发的新手,但是据我所知,解压模式下的 chrome 扩展程序是一个包含一些 html 页面(背景、普通、可选、覆盖、tabs.create/window.open 等)的文件夹和相互通信的 javaScript 文件(内容脚本和其他文件)。这些五花八门的文件让我一头雾水,需要一步步引导。

第一步,如何从 chrome 浏览器扩展中调用 C++ dll?

我已经在 Firefox 插件中使用 js-ctypes 进行了此操作。 是不是和火狐的做法类似?

How to call exported function in a DLL(written using C), from chrome extensions 中解释的一种方法通过将以下代码添加到 manifest.json 来提供调用 dll:

"plugins": [{ "path": "FRViewPortExtn.dll", "public": true },], ...

但是我认为由于在 chrome 中弃用了插件 NPAPI,它不再适用了。

另一种方法是使用Native Messaging,它在https://developer.chrome.com/extensions/nativeMessaging 中引入。我研究了本教程页面的示例,发现它确实强制客户端使用 bat 文件(或可执行文件)。

正如 cmets 中提到的,一个类似的问题在 Loading dll from Chrome extension 但是,答案仅建议使用本机消息传递,而无需任何指示调用 dll 并使用此 dll 功能的示例代码

【问题讨论】:

  • 我猜唯一的选择是nativeMessaging
  • 还可以查看官方扩展文档以消除对所有这些的混淆。问题太宽泛了。在文档中尝试一些东西,然后让我们知道什么不起作用。有一整节专门用于消息传递。
  • 正如@wOxxOm 所说,似乎一个也是唯一的解决方案是使用本机客户端。在here 他们提到扩展可以在没有提示的情况下调用这些。我还没有尝试过,但看起来可以实现,试一试。
  • 这是stackoverflow.com/questions/21163880/…的完全相同的副本
  • 您不应该提出重复的问题,希望得到不同/更好的答案。如果您停留在细节上,而不是您需要使用的一般技术上,请提交一个新问题,显示您尝试使用原生消息传递的内容、您遇到的问题,并询问有关如何继续的具体问题。

标签: javascript api google-chrome google-chrome-extension


【解决方案1】:

我们必须创建两个名为 app 和 host 的文件夹。扩展名是应用程序文件夹,而主机文件夹中提供了与可执行文件的连接。

应用文件夹中的main.html

<html>
  <head>
    <script src='./main.js'></script>
  </head>
  <body>
    <button id='connect-button'>Connect</button>
    <input id='input-text' type='text' />
    <button id='send-message-button'>Send</button>
    <div id='response'></div>
  </body>
</html>

应用文件夹中的main.js

var port = null;

var getKeys = function(obj){
   var keys = [];
   for(var key in obj){
      keys.push(key);
   }
   return keys;
}


function appendMessage(text) {
  document.getElementById('response').innerHTML += "<p>" + text + "</p>";
}

function updateUiState() {
  if (port) {
    document.getElementById('connect-button').style.display = 'none';
    document.getElementById('input-text').style.display = 'block';
    document.getElementById('send-message-button').style.display = 'block';
  } else {
    document.getElementById('connect-button').style.display = 'block';
    document.getElementById('input-text').style.display = 'none';
    document.getElementById('send-message-button').style.display = 'none';
  }
}

function sendNativeMessage() {
  message = {"text": document.getElementById('input-text').value};
  port.postMessage(message);
  appendMessage("Sent message: <b>" + JSON.stringify(message) + "</b>");
}

function onNativeMessage(message) {
  appendMessage("Received message: <b>" + JSON.stringify(message) + "</b>");
}

function  onDisconnected() {
  appendMessage("Failed to connect: " + chrome.runtime.lastError.message);
  port = null;
  updateUiState();
}

function connect() {
  var hostName = "com.google.chrome.example.echo";
  appendMessage("Connecting to native messaging host <b>" + hostName + "</b>")
  port = chrome.runtime.connectNative(hostName);
  port.onMessage.addListener(onNativeMessage);
  port.onDisconnect.addListener(onDisconnected);
  updateUiState();
}

document.addEventListener('DOMContentLoaded', function () {
  document.getElementById('connect-button').addEventListener(
      'click', connect);
  document.getElementById('send-message-button').addEventListener(
      'click', sendNativeMessage);
  updateUiState();
});

window.onbeforeunload= function (e)
{
 message = {"text": "terminate"};
  port.postMessage(message);
   appendMessage("Sent message: <b>" + JSON.stringify(message) + "</b>");
};

应用文件夹中的manifest.json

{
  // Extension ID: knldjmfmopnpolahpmmgbagdohdnhkik
  "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzcp66xi1ctUL0HvndH7IyjNw2CM9TdOMx8XPv0GbQXFmzm3xnqwQkbRYyfNoYN+pIIY0/TRu7qYOAnb0sogEqQRU73sbSAJajPbCxxBTVFueTypQtBpN5uuV/Z/Ox4myMiRVqcfLxDaVLFkVa3f9OGMhWJclDa74eIrwqc81GJQM8TG0JvZMSwE3u8FzH+d8U+x2p/f7a4546BNpP9Ssv2Jc/kE2KV5DIQS++8rg04aHnW3TZX2aUd1Bz+c416hmqxEb4iARGXhg7iURh6KIe9+490imIcXaedhUwWRiqnuJ3Kbkzl/iOSUI2XzIOHxGnkAGmLf9tfsrhKLcwtvvqQIDAQAB",
  "name": "Native Messaging Example",
  "version": "1.0",
  "manifest_version": 2,
  "description": "Send a message to a native application.",
  "app": {
    "launch": {
      "local_path": "main.html"
    }
  },
  "icons": {
    "128": "icon-128.png"
  },
  "permissions": [
    "nativeMessaging"
  ],
  "background":{
     "scripts":["main.js"],
     "persistent": true
     }
}

主机文件夹中的 com.google.chrome.example.echo-win.json 文件

{
  "name": "com.google.chrome.example.echo",
  "description": "Chrome Native Messaging API Example Host",
  "path": "nativeMessaging.exe",
  "type": "stdio",
  "allowed_origins": [
    "chrome-extension://bcffeaabpankpgikpifpailfcihmheno/"
  ]
}

在主机文件夹中安装_host.bat

REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.google.chrome.example.echo" /ve /t REG_SZ /d "%~dp0com.google.chrome.example.echo-win.json" /f

此外,nativeMessaging.exe 及其所需的 dll 可能存在于主机文件夹中

提供这两个文件夹后,您应该运行主机文件夹中的批处理文件以在注册表中注册 json 文件。 最后,你应该通过chrome浏览器上传扩展文件夹(app文件夹)(设置->扩展->加载解压的扩展)。

【讨论】:

    【解决方案2】:

    您可以使用Native Messaging,至于示例代码,您可以查看this answer 了解更多详细信息,它使用 C# 作为服务器端,您可以轻松地将其转换为 C/C++ 或将 dll 导入 C# 项目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-03
      • 2016-06-13
      相关资源
      最近更新 更多