zoukankan      html  css  js  c++  java
  • Chrome Native Messaging 与本地程序之间的通信

       最近项目上出现了web打印不稳定的问题,师父决定web调用本地打印程序,在查阅了相关资料和加了几个相关群咨询后得知新版的chrome不支持NNAPI了,最好用Native Messaging来处理,经过一段时间的学习和试错,终于完成了,所以把步骤与总结发出来。过程参考http://blog.csdn.net/talking12391239/article/details/38498557

       首先,我们需要写一个chrome插件。学习相关知识可以去Chrome扩展及应用开发》这个插件包含了三个文件:manifest.json(这个是插件配置信息文件),background.js(文件名可改, 后台文件),content.js(与页面交互,传递消息给后台)。首先我们来看manifest.json这个文件,

     1 {  
     2     "name" : "myApp",  
     3     "version" : "1.0.1",  
     4     "description" : "Launch APP ",  
     5     "background" : { "scripts": ["background.js"] },  
     6   
     7     "permissions" : [  
     8         "nativeMessaging",  
     9         "tabs",  
    10         "http://*/*"  
    11     ],  
    12     "content_scripts": [  
    13     {  
    14       "matches": ["http://*/*"],  
    15       "js": ["content.js"]  
    16     }  
    17     ],  
    18     "minimum_chrome_version" : "6.0.0.0",  
    19     "manifest_version": 2  
    20 }
    21  

    上面可以看出,这个文件在哪里引用了background.js和content.js,这两个文件的名字是可以更改的,permissions里的"http://*/*"与 content_scripts里的"matches"的意思是允许所有的http请求的url调用。"nativeMessaging" 代表要在这个插件中允许调用这种方法。

        接下来,看一下后台文件background.js:

     1 var port = null;   
     2 chrome.runtime.onMessage.addListener(  
     3   function(request, sender, sendResponse) {  
     4      if (request.type == "launch"){  
     5         connectToNativeHost(request.message);  
     6     }  
     7     return true;  
     8 });  
     9   
    10   
    11 //onNativeDisconnect  
    12 function onDisconnected()  
    13 {  
    14     console.log(chrome.runtime.lastError);  
    15     console.log('disconnected from native app.');  
    16     port = null;  
    17 }  
    18   
    19 function onNativeMessage(message) {  
    20     console.log('recieved message from native app: ' + JSON.stringify(message));  
    21 }  
    22   
    23 //connect to native host and get the communicatetion port  
    24 function connectToNativeHost(msg)  
    25 {  
    26     var nativeHostName = "com.dhcc.lisprint";   
    27     port = chrome.runtime.connectNative(nativeHostName); 
    28     console.log(port)
    29     port.onMessage.addListener(onNativeMessage);  
    30     port.onDisconnect.addListener(onDisconnected);  
    31     port.postMessage({message: msg});     
    32  } 

       这个js文件里有两个十分重要的方法chrome.runtime.onMessage.addListener和connectToNativeHost。chrome.runtime.onMessage.addListener里可以看出,这个响应事件的方式为"launch"时,调用connectToNativeHost。

    connectToNativeHost链接com.dhcc.lisprint这个服务。同时postMessage。

       接下来,我们来看content.js。

    1 var launch_message;  
    2 document.addEventListener('myCustomEvent', function(evt) { 
    3   console.log(evt);
    4   chrome.runtime.sendMessage({type: "launch", message: evt.detail}, function(response) {  
    5   });  
    6 }, false);

      这个文件的意图很明显,当界面传来myCustomEvent这个事件,向后台文件background.js发送type为launch的信息。


      以上就是chrome插件相关部分,我们可以看出并未写如何调用下面介绍native messaging调用部分。首先我们新建一个文件,manifest.json(名称可以修改)。

    1 {
    2     "name": "com.dhcc.lisprint",
    3     "description": "Dhcc imedical lis print config app",
    4     "path": "C:\Test.exe",
    5     "type": "stdio",
    6     "allowed_origins": [
    7         "chrome-extension://acpcejomihdkopjnnijfmnpdgfkmfhkj/"
    8     ]
    9 }

    可以很明显的看出,name即我们background.js里面要调用的host,path即我们要调用的本的应用程序。allowed_origins是什么呢?即我们安装完chrome插件的ID,如图:

    那如何让chrome知道这个json就是com.dhcc.print的配置文件呢?这里我们还需要进行下一步,修改注册表:

    运行-> Regedit -> HKEY_Current_User->Software->Google->Chrome->新建一个叫NativeMessagingHosts的项->新建一个叫com.my_company.my_application的项,  同时在这个项里默认值设置为我们Native Messaging 的 位置 即这个json文件的位置,如C:\Native\manifest.json。这样便完成了native masseging的设置。


    接下来我们看界面是如何调用的

    <html>
    <head>
        <script>
    
    function startApp() {
        var evt = document.createEvent("CustomEvent");
        evt.initCustomEvent('myCustomEvent', true, false, "哈哈哈哈");
        // fire the event
        document.dispatchEvent(evt);
    }
    
        </script>
    </head>
    <body>
        <button type="button" onClick="startApp()" id="startApp">startApp</button>
    </body>
    </html> 

    里面有一个简单的按钮, 这个按钮会启动方法, 新建一个名叫"myCustomEvent"的事件, 同时附带有我们要传的信息, 并发布这个事件。 这样我们插件中的Content.js 就可以接收并响应这个事件了!

    下面,我们可以看下如何接收页面传递给exe的信息。

     1  private void Form1_Load(object sender, EventArgs e)
     2         {
     3             string chromeMessage = OpenStandardStreamIn();
     4 
     5             MessageBox.Show(chromeMessage);
     6 
     7         }
     8 
     9         private static string OpenStandardStreamIn()
    10         {
    11             //// We need to read first 4 bytes for length information  
    12             Stream stdin = Console.OpenStandardInput();
    13             int length = 0;
    14             byte[] bytes = new byte[4];
    15             stdin.Read(bytes, 0, 4);
    16             length = System.BitConverter.ToInt32(bytes, 0);
    17 
    18             string input = "";
    19             for (int i = 0; i < length; i++)
    20             {
    21                 input += (char)stdin.ReadByte();
    22             }
    23 
    24             return input;
    25         }

    以上就是全部内容啦~


  • 相关阅读:
    const修饰指针
    C++调用C中编译过的函数要加extern "C"
    linux常用指令(1)
    链式队列实现
    存储类别和类型限定词
    数组,指针和引用
    字符函数和字符串函数
    C/C++编译的程序占用的内存
    结构体1(嵌套使用)
    输入输出函数小结
  • 原文地址:https://www.cnblogs.com/real9527/p/4970858.html
Copyright © 2011-2022 走看看