最近项目上出现了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 }
以上就是全部内容啦~