最近遇到一個新的問題。需要使用Chrome 插件, 從我們對我們當地的一個網站之一啟動C#應用,同時通過本申請值執行不同的操作。
在這里記錄下解決的過程。以便以后查找
首先我們須要新建一個google的插件 這個插件包括了三個文件
manifest.json(名字不可改, 建插件必須文件),background.js(文件名稱可改, 后台文件),content.js(content script文件 負責與站點頁面交互)
首先我們來看看manifest.json 這個文件
<span style="font-family:SimSun;font-size:18px;">{ "name" : "FastRun", "version" : "1.0.1", "description" : "Launch APP ", "background" : { "scripts": ["background.js"] }, "permissions" : [ "nativeMessaging", "tabs", "http://xxx/*" ], "content_scripts": [ { "matches": ["http://xxx/*"], "js": ["content.js"] } ], "minimum_chrome_version" : "6.0.0.0", "manifest_version": 2 }</span>
里面的premissions很重要, 他表示我們的插件在什么條件執行, "nativeMessaging" 代表要在這個插件中同意調用這樣的方法
"xxx"填入你想要的加載的網址
"content_scripts" 中"xxx" 表示在什么網頁下執行我們與界面交互的script.
再來看看后台文件
background.js
var port = null; chrome.runtime.onMessage.addListener( function(request, sender, sendResponse) { if (request.type == "launch"){ connectToNativeHost(request.message); } return true; }); //onNativeDisconnect function onDisconnected() { console.log(chrome.runtime.lastError); console.log('disconnected from native app.'); port = null; } function onNativeMessage(message) { console.log('recieved message from native app: ' + JSON.stringify(message)); } //connect to native host and get the communicatetion port function connectToNativeHost(msg) { var nativeHostName = "com.my_company.my_application"; console.log(nativeHostName); port = chrome.runtime.connectNative(nativeHostName); port.onMessage.addListener(onNativeMessage); port.onDisconnect.addListener(onDisconnected); port.postMessage({message: msg}); }
在這個文件中有兩個方法很重要
chrome.runtime.onMessage.addListener
和
connectToNativeHost
先來看第一個方法。
是一個響應事件。當接收到類型為"launch"的消息時, 調用 connectToNativeHost方法並傳入數據。
com.my_company.my_application
這個是我們之后須要注冊在Regestry和Native Messaging里面的名字 之后會講到。
runtime.connectNative這種方法連接我們的Native Messaging然后利用 postMessage 去發送我們要的信息給我們的本地應用
當然這里我們能夠替換為 sendNativeMessage 直接給本地應用傳值詳見
https://developer.chrome.com/extensions/runtime#method-connectNative
我們在來看看ContentScript: content.js這個文件
<span style="font-family:SimSun;"><span style="font-size:18px;">var launch_message; document.addEventListener('myCustomEvent', function(evt) { chrome.runtime.sendMessage({type: "launch", message: evt.detail}, function(response) { console.log(response) }); }, false);</span><strong> </strong></span>非常easy, 響應了一個頁面中的事件"myCustomEvent", 同一時候公布一個消息給我們的后台文件background.js,這個消息包括了消息標示 "launch" 和 我們要傳的值 evt.detail
關於Content Script 的信息 詳見 https://developer.chrome.com/extensions/content_scripts
到這里我們的google插件部分就做好了
別忘了在Chrome 插件里開啟開發人員模式 並載入這個插件
-------------------------------------切割線-------------------------------------
我們在來看看 Native Messaging 部分 我們再建一個 json 文件 我這里也叫做manifest.json(名字能夠不是這個) 存在了我本地C:/Native文件夾下
<span style="font-family:SimSun;font-size:18px;">{ "name": "com.my_company.my_application", "description": "Chrome sent message to native app.", "path": "C:\\MyApp.exe", "type": "stdio", "allowed_origins": [ "chrome-extension://ohmdeifpmliljjdkaehaojmiafihbbdd/" ] }</span>
這里我們定義了 Native Messaging 的名字, 在path中定義了我們要執行的本地應用程序, allowed_origins 中長串的字符是我們插件的id 能夠在安裝插件后從google chrome 插件里看到(安裝插件 能夠在chrome中插件開啟開發人員模式並加載我們之前的插件文件包)
完畢這步以后我們須要在WIndows 注冊表 中增加google 項目詳細例如以下:
執行-> Regedit -> HKEY_Current_User->Software->Google->Chrome->新建一個叫NativeMessagingHosts的項->新建一個叫com.my_company.my_application的項, 同一時候在這個項里默認值設置為我們Native Messaging 的 位置 C:\\Native\\manifest.json
這樣我們就完畢了NativeMessaging的設置
-------------------------------------我是切割線-------------------------------------
我們再來看看這個插件怎樣和我們的站點交互
先建一個簡單的網頁內容例如以下
<span style="font-family:SimSun;font-size:18px;"><!DOCTYPE HTML> <html> <head> <script> function startApp() { var evt = document.createEvent("CustomEvent"); evt.initCustomEvent('myCustomEvent', true, false, "im information"); // fire the event document.dispatchEvent(evt); } </script> </head> <body> <button type="button" onClick="startApp()" id="startApp">startApp</button> </body> </html> </span>
里面有一個簡單的button, 這個button會啟動方法, 新建一個名叫"myCustomEvent"的事件, 同一時候附帶有我們要傳的信息, 並公布這個事件。 這樣我們插件中的Content.js 就能夠接收並響應這個事件了!
-------------------------------------我是切割線-------------------------------------
我們最后再來看看C#程序, 隨便做一個很easy的程序, 放到了
C://MyApp.exe這里
在Main里面 我們能夠增加以下這種方法, 利用Console.OpenStandardInput這個 我們能夠接收到由頁面傳到我們應用的值並進行我們想要的一些操作, 在這里我們用一個log4net 記錄我們程序執行情況
[assembly: log4net.Config.XmlConfigurator(Watch = true)] namespace MyApp { static class Program { public static log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); [STAThread] static void Main(string[] args) { if (args.Length != 0) { string chromeMessage = OpenStandardStreamIn(); log.Info("--------------------My application starts with Chrome Extension message: " + chromeMessage + "---------------------------------"); } } private static string OpenStandardStreamIn() { //// We need to read first 4 bytes for length information Stream stdin = Console.OpenStandardInput(); int length = 0; byte[] bytes = new byte[4]; stdin.Read(bytes, 0, 4); length = System.BitConverter.ToInt32(bytes, 0); string input = ""; for (int i = 0; i < length; i++) { input += (char)stdin.ReadByte(); } return input; } } }
點擊我們在頁面上增加的button, 然后檢查log文件:
2014-07-30 09:23:14,562 [1] INFO MyApp.Program ----------------------------------------My application starts with Chrome Extension message: {"message":"im information"}---------------------------------
最后一張圖總結下整個過程
假設想要在安裝我們本地軟件時安裝這個插件, 我們須要把我們的插件先公布到Chrome web store上詳見https://developer.chrome.com/extensions/external_extensions
我將不贅述
版權聲明:本文博客原創文章。博客,未經同意,不得轉載。