Google chrome瀏覽器中通過擴展調用本地應用程序以及和程序相互通訊(C++)


最近項目用到瀏覽插件的開發,IE用到的是BHO,chrome打算做成擴展。

但是和ie有一點不同,chrome擴展是基於html+js+css開發的,那么就會有二個問題
1. 代碼和算法等容易被別人復制和盜用。
2. 有部份功能需要用native code來實現。

所以僅僅使用chrome擴展是不夠的。后來想到了native client,但是這個需要在chrome://flags/中開啟相應的設置。而且也不是很安全。
最后選擇了chrome的native messaging,原理我就不多說了,這里只介紹如何實現。

chrome擴展中,manifest.json有幾點要注意

"background": {
    "scripts": [
        "res/js/background.js"
    ]
},

上面個background.js,是必須要加的,后面會介紹原因

"content_scripts": [
    {
        "all_frames": false,
        "css": [
        ],
        "js": [
            "res/js/contentscript.js"
        ],
        "matches": [
            "http://*/*",
            "https://*/*"
        ],
        "run_at": "document_end"
    }
],

這個表示在頁面加載結束時調用contentscript.js

"permissions": [
    "nativeMessaging"
],

權限別忘了加上。

contentscript.js中,只有一段代碼

$(function () {
chrome.extension.sendRequest("this is a request");
});

重點在background.js中了,不多說,貼代碼

var port;
function onDisconnected() {
port = null;
}

function onNativeMessage(message) {
alert(JSON.stringify(message));
}

function connect() {
port = chrome.runtime.connectNative('com.beeper2g.demo.nativemessage');
port.onMessage.addListener(onNativeMessage);
port.onDisconnect.addListener(onDisconnected);
}

chrome.extension.onRequest.addListener(function(data, sender) {
if (data.length > 0) {
connect();
port.postMessage(data);
}
});

注意方法 chrome.runtime.connectNative 是屬於content script,這個不能在頁面中調用,所以只能放在backgroud.js中,上面提到過。

擴展中的東西就這么些,講一下注冊以及調用方式

注冊和解注冊就是在注冊表中添加相應的值就OK了,發二個bat,一個install,一個uninstall

install.bat內容為
:: %~dp0 is the directory containing this bat script and ends with a backslash.
REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.beeper2g.demo.nativemessage" /ve /t REG_SZ /d "%~dp0com.beeper2g.demo.nativemessage.json" /f

uninstall.bat內容為
:: Deletes the entry created by install_host.bat
REG DELETE "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.beeper2g.demo.nativemessage" /f

其中的com.beeper2g.demo.nativemessage.json中內容十分簡單
{
"name": "com.beeper2g.demo.nativemessage",
"description": "Demo程序",
"path": "X:\XXX\chromeService.exe",
"type": "stdio",
"allowed_origins": [
"chrome-extension://fkdejdpefhhjdjdlmalkegclifdofipm/"
]
}
字段自己去對應,path為絕對路徑。chrome-extension://fkdejdpefhhjdjdlmalkegclifdofipm/ 中的id別忘了與擴展一致

c++部份
// chromeHost.cpp : Defines the entry point for the console application.
//

using namespace std;

void output(const string& str)
{
unsigned int len = str.length();
cout<< char(((len>>0) & 0xFF))
<< char(((len>>8) & 0xFF))
<< char(((len>>16) & 0xFF))
<< char(((len>>24) & 0xFF));
cout << str << endl;
}

string getInput()
{
string input;
unsigned int reqLen = 0;
cin.read(reinterpret_cast<char*>(&reqLen) ,4);
for (int i = 0; i < reqLen; i++) {
input += getchar();
}
return input;
}

int main(int argc, char* argv[]) {
string input = getInput();
MessageBoxA(NULL, input.c_str(), NULL, NULL);
output("this is response");
return 0;
}

重中之重就是注意通訊中都有四個字節的包頭,表示包的大小,這個不能丟,否則不會成功。


免責聲明!

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



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