如果想讓你的 binary 軟体元件在瀏覽器上能夠執行, 你需要實做一些規定的介面. 這樣的程式就能像 Flash 一樣, 嵌入在網頁中, 讓使用者使用. 然而不同的瀏覽器要實做的介面是不一樣的.
若你希望在 IE 上要能執行, 則你的元件必須實做 ActiveX 的介面
若你希望在 Firefox 或 Opera 甚至是 Google 的 Chrome 瀏覽器上也能執行你的程式, 那麼你的元件必須實做 NPAPI 介面.
這一切都要怪微軟是屬於封閉架構, 這使得一些跨平台的軟体開發組織, 不願意實做 ActiveX. 所以如果你要讓 firefox 或新的 Goolge 瀏覽器 Chrome 上面寫 plugin, 你能用的技術是 NPAPI.
這份文件內容包含
1. 如何選擇正確的方式, 撰寫 scriptable plugins
2. 如何下載正確的 NPAPI 範例
3. 如何在 Visual Studio .Net IDE 下, 編譯範例
4. 如何測試你的 plugin
------------------------------------------------------------------
選擇正確的方式, 撰寫 scriptable plugins
我想你應該知道 Plugins 與 Extensions 是不一樣的, 你想知道 Firefox Plugin 的最新發展, 應該到
你可以用 plugin 多媒體應用程式, 例如監控系統, 人物自動追蹤 等應用, 全部都可以利用 NPAPI 這個介面讓你的應用程式網頁化.
官方網頁裡面詳細的告訴你, NPAPI plugins 可以利用 java script 進行操控, 而舊的技術 XPCOM 和 LiveConnect 已經不適合用來開發 NPAPI plugins 了.
要讓 plugins 能被 script 操控, 你應該使用 npruntime
網址: http://developer.mozilla.org/en/Gecko_Plugin_API_Reference/Scripting_plugins
有圖有真相
寫程式也是一樣, 與其看一堆文件, 先給我一個能執行的範例. 再談後面的優秀架構與API 文件.
所以呢 ...
有程式還要能 work 才有真相! 你看看, 菜不就端上來了嗎 ....
我知道你在想什麼, 下面的範例支援 Firefox 3.0.
如何寫程式?
Step 1: 下載 Gecko_SDK: xurlrunner
網址: http://developer.mozilla.org/en/Gecko_SDK
* 我下載的是 Gecko 1.9 (Firefox 3.0) 版本
Step 2: 下載範例程式
網址: http://mxr.mozilla.org/seamonkey/source/modules/plugin/samples/
點選 npruntime 範例
每個檔案都有 Raw file 可以讓你下載, 把所有的檔案下載回去吧!
注意: 你會在 Samples and Test Cases 發現, 範例程式有兩個載點, 其中第二個mozilla/modules/plugin/tools/sdk/samples 裡面, scriptable 使用的是舊的技術 XPCOM, 請不要使用. 否則你編出來的 dll 在 Firefox 3.0 會無法執行.
Step 3: 建立一個簡單 Visual Studio 專案, 把剛剛抓到的程式放進去.
mozilla 官方網頁有教學: 你可以去看一下 (link)
下面是我寫的簡單修正中文版 (別擔心, 這些流程都很簡單)
----------------------------------------
1. 建立新的專案: project 名稱設定為 nprt
VC 的操作: New Project -> Vistual C++ -> Win32 Project
2. Application Settings 選 DLL 並且設定為 Empty project
3. 把範例程式加入專案中
(a) 把從 http://mxr.mozilla.org/seamonkey/source/modules/plugin/samples/
下載回來的所有檔案 copy 到 nprt/nprt 目錄中
(b) 加入 nprt 專案中
4. 解開 xulrunner-sdk: 放在 C:\xulrunner-sdk
網址:http://developer.mozilla.org/en/docs/Gecko_SDK
5. 設定 Include Path
VC 的操作: C/C++ -> Additional Include Directories
"C:\xulrunner-sdk\include";"C:\xulrunner-sdk\include\plugin";"C:\xulrunner-sdk\include\nspr";"C:\xulrunner-sdk\include\java"
6. 直接設定下面的定義
VC 的操作: C/C++ -> Preprocessor -> Preprocessor Definitions
WIN32;_WINDOWS;XP_WIN32;MOZILLA_STRICT_API;XPCOM_GLUE;XP_WIN;_X86_;NPSIMPLE_EXPORTS
_DEBUG
7. 關掉 precompiled 選項 (如果你剛剛選的是 Empty Project, 則 precompiled 選項應該已經關閉)
VC 的操作: C/C++ -> Precompiled Headers -> Create/Use Precompiled Header: 設定為 Not Using Precompiled Headers
8. 設定 Module Definition File: nprt.def
VC 的操作: Linker -> Input -> Module Definition File:
9. 把 plugin.cpp 的 DrawText 改成 DrawTextA
10. 修改 plugin.cpp 裡面的 Invoke method 改成下面這樣,
否則當 firefox 呼叫你的 plugin 時, 會 當掉.
------------------------------------------------------------------
bool ScriptablePluginObject::Invoke(NPIdentifier name, const NPVariant *args,
uint32_t argCount, NPVariant *result) {
if (name == sFoo_id) {
printf ("foo called!\n");
MessageBox(NULL,L"foo 被呼叫 ",L"Java Script 呼叫範例",MB_OK);
return PR_TRUE;
}return PR_FALSE;
}------------------------------------------------------------------
11. 修改 npp_gate.cpp , 把 _GetJavaClass 拿掉
------------------------------------------------------------------
/* 加入註解 (感謝網友 Chui-Wen Chiu 提醒)
jref NPP_GetJavaClass (void)
{
return NULL;
}*/
------------------------------------------------------------------
編譯應該會通過, 產生 nprt.dll
----------------------------------------
測試:
Step 1: 把 nprt.dll 放到 firefox 的 plugins 目錄底下
Step 2: 開啟 firefox 在網址輸入
about:plugins
看看你的 plugins 是否在裡面.
長相應該是這樣.
Step 3: 執行 測試 test.html
注意 1: 你下載的 test.html 已經嚴重過期了. 所以我的作法是自己寫一個
希望對你有幫助, Enjoy.
by Jing (井民全)
延伸參考資訊
[3] Gecko_SDK 下載地點
[4] 一堆 NPAPI 範例
真是好文
回覆刪除我用 VS2005 依據你的步驟進行
還需要 移除 npp_gate.cpp 的
jref NPP_GetJavaClass (void)
{
return NULL;
}
地方才能順利編譯
對阿, 我忘了把他寫進去.
回覆刪除你能不能給我點建議,我現在才剛剛開始寫NPRUNTIME PLUGIN,
回覆刪除USE NPAPI EXTENSION,
我不知道具體的程序格式,你能不能發給我一個最簡單的PLUGIN sample以及測試頁面,讓我知道NPRUNTIME PLUGIN的程序框架寫法。
非常感謝
郵箱:fifawqm@163.com
QQ:6326662
您文章的東西我都調試通過了,也可以把例子里的關鍵功能函數改成我自己的,我就是不知道怎么從頭寫一個PLUGIN,想你給我一個最簡單的PLUGIN以及測試頁面,讓我從中可以學習其書寫格式,不勝感謝。
回覆刪除郵箱:fifawqm@163.com
QQ:6326662
這篇文章的教學是從頭建立一個新的專案, 然後把範例一個一個加進來. 確實不符合您的需求.
回覆刪除測試頁面在文件的最後, 請檢查一下. http://mqjing.twbbs.org.tw/~ching/test2_html.txt
不過你應該可以從可以 nprt 的 cpp 原始程式檔中, 看出一些端倪. 因為他已經提供了基本的功能, 從這裡下手這樣最快.
要不然, 可能要請你看一下完整的說明了. 網址如下:
http://developer.mozilla.org/en/Gecko_Plugin_API_Reference
不好意思, 我沒有幫到你什麼忙.
by Jing
謝謝你 http://developer.mozilla.org/en/Gecko_Plugin_API_Reference 我也看了 就是不得其所 主要是不知其格式 NPRUNTIME這個例子我已經調通 并用你的測試頁面達到我要達到的效果
回覆刪除再次謝謝你
有個問題想請教,
回覆刪除這篇是關於firefox3的plugin的開發,
那如果是firefox2上的plugin呢?
我有去抓firefox-2.0.0.17-source
及firefox-3.0.3-source
在mozilla\modules\plugin\samples目錄下都有一些sample project
npruntime這個project只有在firefox-3.0.3-source有
而且gecko-sdk-1.8不能compile這個projetc裡的檔案,gecko-sdk-1.9才可以
我試著用gecko-sdk-1.8 建一個project去compile "4x-scriptable"這個目錄裡的file,compile有過而且把compile好的dll copy到$firefox_ install_path$\plugins這個 folder
xpt檔 copy到$firefox_installpath$\components這個folder,不過在firefox打about:plugins還是看不到新增加的plugin,請問有哪ㄒㄧ些要注意的地方??感謝...
my email:chunkai.hwang@gmail.com
firefox 3.0
回覆刪除要安裝 plugin 最簡單的手動方法是直接將 np*.dll 複製到 firefox 的 plugins 目錄裡面.
另一個方法是把 dll 封裝成 xpi, 然後讓瀏覽器自行安裝.
html 檔可以寫成這樣:
embed type="application/basic-plugin"
pluginspage="file:///E:/abc.xpi"
name="basic"
autoplay="no" loop="yes" width="400" height="200"
至於 firefox 2.0 我就不清楚了. 你可以先試試看直接 copy dll 到 pugins 先看看會不會動.
by Jing.
再請教一下
回覆刪除關於firefox2.0 的plugin我後來用"4x-scriptable"這個使用xpcom架構的sample去改已經可以動了,
firefox3.0的plugin用"npruntime"這個sample去改也可以動,不過必需要是原先一開始就是安裝firefox3,如果是firefox2更新到firefox3則有一些問題,主要是plugin export給java script呼叫的method或property在回傳字串時會有問題,firefox會整個hang住,method若是回傳int則沒有問題,我傳回字串是用以下的方式
bool ScriptablePluginObject::Invoke(NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result) {
if (name == sFoo_id) {
string strRet="xxxxxxx";
STRINGZ_TO_NPVARIANT(strdup(strRet.c_str()),*result));
return PR_TRUE;
}
return PR_FALSE;
請問還有其它作法可以解這個問題嗎?感謝
請問如何調試nprt.dll?我想通過firefox console將nprt.dll中用printf()和OutputDebugStringA()的消息輸出。或者有沒有別的方法?比如,通過vs 2005的IDE直接調試等。謝謝!
回覆刪除我後來發現firefox2.0的plugin(compile with gecko sdk 1.8)也可以在firefox3.0上跑,而且沒有firefox2 upgrade到firefox3.0 string方面的問題
回覆刪除劳驾问一下:创建带界面的firefox插件如何做?
回覆刪除能否给点提示?非常感谢?
希望我没有打扰您。
我想向您请教一个问题。
回覆刪除在javascript中有 script for="plugin id" event="event string"
这样用来注册的语法,不知道在npapi中是如何来支持这样的注册方式的。我尝试了很多次,页面中这样的语句并不会导致hasmethod或是hasproperty,或invoke等方法被调用。请您给出些建议或看法,好吗?我的邮箱是zhoufeng_nwpu@yahoo.com.cn,欢迎你来信讨论。
----felix
照你说的方法,我在windows上达到预期效果,但是我在linux编译把cpp文件编译成so文件后,放入/usr/lib/mozilla/plugins,结果firefox没有找到我的插件,请问这是为什么,中间少了什么步骤吗? 谢谢
回覆刪除因為我沒有在 linux 上編程的經驗, 所以可能無法給您有幫助的答案.
回覆刪除I had the same problem with the npruntime sample. The fix for that is to allocate memory using NPN_MemAlloc().
回覆刪除STRINGZ_TO_NPVARIANT(strdup("foo return val"), *result);
becomes
char * myStr = (char *)NPN_MemAlloc(32);
strcpy(myStr, "helloWorld");
STRINGZ_TO_NPVARIANT(myStr, *result);
你好,看了你的如何开发firefox的plugin问题的blog,非常有帮助。感谢。现在有一个问题请教一下:
回覆刪除1.我写了一个简单的plugin,dll已经编译成功了。而且用您的测试的html文件测试,执行成功。
但是,如何在extension的js中调用这个函数呢?
我现在有一个extension的框架,这个extension类似gmail notifier。点击这个extension的某一个button,调用的函数:
gm_notifier.prototype.checkNow = function() {
// 如何调用dll中的BugNotifier函数?
}
非常感谢,希望能够得到您的回复netinj@gmail.com
你好,看了你的如何开发firefox的plugin问题的blog,非常有帮助。感谢。现在有一个问题请教一下:
回覆刪除1.我写了一个简单的plugin,dll已经编译成功了。而且用一个测试的html文件测试,执行成功。
但是,如何在extension的js中调用这个函数呢?
我现在有一个extension的框架,这个extension类似gmail notifier。点击这个extension的某一个button,调用的函数:
gm_notifier.prototype.checkNow = function() {
// 如何调用dll中的BugNotifier函数?
}
非常感谢,希望能够得到您的回复netinj@gmail.com
請看文章 Step 10
回覆刪除bool ScriptablePluginObject::Invoke(NPIdentifier name, const NPVariant *args,
uint32_t argCount, NPVariant *result) {
if (name == sFoo_id) {
printf ("foo called!\n");
MessageBox(NULL,L"foo 被呼叫 ",L"Java Script 呼叫範例",MB_OK);
return PR_TRUE;
}
return PR_FALSE;
}
有看到 sFoo_id 嗎?
你可以從這裡追查下去, 我想應該能解答你的答案.
恩,感谢你的回复。
回覆刪除文章中的例子我都调试通过了,而且在test2.html测试成功。
但是这篇blog中是在html里调用我们自己定义的function。在extension里如何调用呢?extension的js里不是在html里的。。。
盼答。感谢。
我用你的方法在vs2008實作.在firefox及Opera上運作正常.但是在Goole的chrome及Apple的Safari上呼叫Foo(),卻無法進入plugin.cpp中ScriptablePluginObject 的Invoke(...)是否需要作一些修改.
回覆刪除非常感謝
email:david945@gmail.com
请问你的范例能用VB 实现吗,
回覆刪除请问 你的范例能用VB实现吗,
回覆刪除我不知道 VB 可不可以, 不過如果想避開一堆有的沒的問題, 我想最好還是使用 C++ 會比較好.
回覆刪除利用您的方法,可以在電腦上成功建立plugin,並使用正常;但是當將此dll檔複製到非開發平台上的plugins目錄中,似乎無法使用,利用您另一篇文章的xpi作法,也有類似的問題,可否提供建議,謝謝
回覆刪除你應該漏掉一些必要的 dll 檔, 系統找不到, 才會遇到這種問題.
回覆刪除檢查一下.
1. 你有沒有用到 MFC 的 dll
2. 你的專案程式是否有用到其他 dll
謝謝您的建議,不過我目前是使用nprt的sample並以vs2005方式進行實驗(如您範例的步驟),並未包含其他dll檔;當其他電腦開啟此一網頁時,同時將nprt.dll檔先行放入plugins的目錄中,瀏覽器並不會出現要下載外掛程式的訊息,只是應該有npapi運作的地方,沒有出現任何東西,
回覆刪除不知您有無建議的驗證方向?
謝謝
拜讀您的文章真的讓我收穫良多.
回覆刪除請問您知不知道有沒有什麼辦法可以讓Firefox不需要重新開機就載入Plugin的呢?
目前我的做法都是要將Plugin 複製到 Firefox 的 Plugins 目錄,然後重新啟動 Firefox,則此Plugin才會生效.
還望您指教看看有沒有什麼好方法? Thanks.
您好,再次的感謝您這篇很棒的分享. 我也有碰到 nprt.dll 換到不同 PC 就無法 work 的現象. 不知您是否有任何的建議呢? Thanks.
回覆刪除關於nprt.dll 無法搬到另外的電腦執行的原因我找到了. 似乎是因為原本的專案名稱取得太長了(超過8個字). Compile 後的 DLL 檔變得不太正確. 即使我將 DLL 檔 rename 變短後也沒有用. 要從 Compile Option 中將名字改短,竟然就解決了.
回覆刪除此心得也分享給您. Thanks. :)
把 plugin 直接拉進 firefox 視窗內, 就會自動安裝了. 還是我搞錯你的意思了.
回覆刪除請問有使用JAVA的例子嗎?
回覆刪除您好,我是最近開始研究npapi的程式人員~
回覆刪除觀看您的文件的確令人驚喜,只是我照您提供的步驟方法卻一直卡住,無法編譯,希望您能撥空指點在下~
1. 我是使用visual studio 2005(中文)來進行compile,在新增專案時選擇win32 專案的話會無法顯示c++的編譯標頭檔,導致後面步驟編譯有問題
2. 若採用了其它專案的設定強制編寫後,則會發生"NP_GetEntryPoints"入口錯誤等等的訊息,最後也無法編譯成功。
希望您這邊能提供一些資訊或經驗,謝謝~
你好,
回覆刪除我使用你所說的例子,在vs2008/gecko-sdk1.9.1下改写了一个简单的plugin dll,不使用messagebox,而是使用mfc的dialog box,簡單的只有單純的訊息及OK鍵與cancel鍵,dll已经编译成功了。而且用一个测试的html文件测试,在xp/vista/window7上使用firefox 3.x版执行,使用滑鼠點擊OK鍵與cancel鍵都很正常。使用firefox 4.0.1在xp/vista也很正常,但是使用firefox 4.0.1在window7上點擊dialog box上的OK鍵與cancel鍵都沒有反應.不曉得是否有人有同樣的問題,如何解決?
請問關於NPAPI或是相關的火狐AddOns可以進行底層裝置的操作,像是Serial Port讀寫嗎?最近剛接觸這一塊,看了一些文章都沒有提到類似的應用,會是火狐瀏覽器為了安全性而將這功能關閉,所以無法像ActiveX能在IE上控制Serial Port嗎?
回覆刪除在別的網站(ActiveComport Serial Port Toolkit)看到火狐透過ActiveX plugin連接ActiveX進行控制,不過只能在Windows環境下運作。是否真的無法直接以Plugins來操作?才需要透過ActiveX plugin?
關於 vs2010
回覆刪除從 mozilla 上拿下來的 rc and h file 無法通過 vs2010 的編譯會出現 "unexcept end of file"
solution :
目的 : 拿到可以讓 2010 編譯過的 rc 跟 h 檔
方法 : 1. 從 vs2010 從新開起一個 win32 Application 專案,
application type 選 DLL
commmon header file 選 MFC
2. 複製其中的 rc 跟 h 檔, 放置到原先無法編譯過的專案中, 並且覆蓋上去
3. 重新編譯 DLL