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         }

以上就是全部內容啦~

 


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM