So Tired !_! 逆水行舟, 不进则退!

26Jul/12

解决IIS7返回header里面的date值不正确导致firefox里cookies无效的问题.

Posted by Nick Xu

问题:

突然有一天,easybug.net上的登录功能无法使用,原本以为是自己电脑有问题,所以没有理会.后来又有好些用户反应无法登录.我就奇怪了,最近都没有更新过什么,怎么会突然就登录不了了呢.

用了很多方法都没有查到具体的原因,后来因为我点击切换语言的时候,发现这个功能也失效了.所以大致的原因可以锁定在cookies上了.用firebug上的net和cookies模块来监控http请求和cookies的值,发现在net里面是有带了cookies,但是在cookies标签里却看不到系统创建的cookies,就是说浏览器没有把cookies写入到浏览器里面,查了半天没找到什么原因,太神奇了...

后来想想既然在net标签里都已经有cookies信息了,那浏览器应该也是收到的了,会不会是在header里有什么问题呢?果然,看到一个很奇特的信息,在header里面看到这么一行信息:

date:2013-7-25 19:32:28

奇怪了,怎么日期是2013年呢,现在才2012年呢...于是顺藤摸瓜,查一下http协议相关的资料,果然被我查到这样一篇内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Problem Description
 
W3SVC logs show incorrect time - stuck on the same time 2007-11-04 04:56:06
REPRO STEPS
 
    Changed the system time to a future time (e.g. 11th May 2020)
    Browsed any site - verified the log file created in the new date/time
    Changed the system time to be correct (today's date and time)
    Now, browsed any website and saw that the time on the log files is now stuck on 11th May 2020's time
 
RESOLUTION
 
    net stop http
    net start w3svc
 
OR
 
    net stop http
    net start http
    iisreset
 
You must restart the http service whenever you change the date in the server.
 
Verified in the code and confirmed that this is by design and you need to follow the above steps to make IIS logging the correct time.

 

大致的意思是在IIS上,如果修改了服务器当前的日期到2020年,然后访问服务器上的站点,日志文件会以当前日期来记录日志内容,此时再把服务器上的日期修改回正确的日期,再访问站点,日志文件里的日期还是2020年的日期,不会自动修改回来,要解决这种问题,只有重启IIS,而且还一定要重启http这个服务,不然不会有效果的.我按上面的步骤试了一下,再来看一下header里面的date,果然现在已经是正确的值了,试一下登录easybug.net,yeah!!登录成功了!!!

总结出现以上问题的原因来自几个方面:
1. 这算是IIS的一个小小的BUG,不过为何会出现日期不一至呢?大部分是人为的原因造成的.
2.各个浏览器里面,好像只有Firefox在IIS出现这种情况的时候有问题,其它浏览器没有问题.
3.通过设置cookies的失效时间大于header里面date的时间应该也可以解决这个问题,不过没有去测试.
4.百年一遇的情况,RP问题啊:(

 

21May/10

如何為你的 firefox plugin 加上新的 method

Posted by Nick Xu

最簡單最笨的操作步驟如下:

Step 1: 加入 method 名稱標記
    在 plugin.cpp 中的 CPlugin method 中加入 method 的標記

ex:
    CPlugin::CPlugin(NPP pNPInstance) ..{

            MYfunction_id=NPN_GetStringIdentifier("MYfunction");
    }

Step 2: 宣告 method 名稱標記 

ex:
    static NPIdentifier MYfunction_id;

Step 3: 告訴別人你的元件有這個 method
ex:
    bool ScriptablePluginObject::HasMethod(NPIdentifier name){
        if(name == MYfunction_id)
            return true;
    }

Step 4: 當 script 呼叫你的 method 時, 提供你 method 的實做

ex:
    bool ScriptablePluginObject::Invoke(NPIdentifier name, const NPVariant *args,uint32_t argCount, NPVariant *result) {
          DWORD dwThreadID;

         if(name == MYfunction_id ){
            MessageBox(NULL,L"呼叫 MYfunction_id",L"Java Script 呼叫範例",MB_OK);
            return PR_TRUE;
          }

          return PR_FALSE;
    }

如何讓 JavaScript 傳參數給你的 plugin method 呢?

如果 Java Script 呼叫的 method 有參數, 我們要如何取出參數資料呢
例如:
    Myfunction("192.168.0.1",1234);

=== in Invoke method ===
// 第一個參數: "192.168.0.1"
    NPVariant varIP=args[0];
    NPString npstrIP=NPVARIANT_TO_STRING(varIP); // 取出 "192.168.0.1"
    // 印出來看看: 將 utf8 字串 轉成 Wide Char
    int   length=MultiByteToWideChar(CP_UTF8,0,(char*)npstrIP.utf8characters,-1,NULL,0);
    TCHAR *strIP=new TCHAR[length];
    MultiByteToWideChar(CP_UTF8,0,(char*)npstrIP.utf8characters,-1,strIP,length);
    MessageBox(NULL,strIP,_T("呼叫 funPassVar_id: 第一個參數n"),MB_OK);
    delete[] strIP;

    // 第二個參數: 1234
    NPVariant varValue=args[1];
    int32_t value=NPVARIANT_TO_INT32(varValue);

    //印出來看看: 印出 int32 的內容
    TCHAR msg[100];
    _stprintf(msg,_T("value=%d"),value);
    MessageBox(NULL,msg,_T("呼叫 funPassVar_id: 第二個參數n"),MB_OK);
=============================================

希望對你有幫助.

by Jing

21May/10

如何让Firefox Plugin可以在网页中自动安装

Posted by Nick Xu

打包plugin作为xpi(zip)文件

Step 1: 先把你那一堆 dll (包含 np開頭的 dll) 放進 plugins 目錄裡面

snap003

Step 2: 撰寫 install.rdf (安裝描述檔), 放在如上圖的相對位置

ex: 反正照抄就對了 (注意 em:id, em:name 要改成你的名字)

snap003

詳細格式說明: https://developer.mozilla.org/en/Install.rdf

Step 3: 產生 Firefox 自動安裝檔 -- xpi 檔

只要下達這個指令即可:

jar cvfM 你的檔案.xpi -C ./ *.*

(注意:

1. xpi 其實是 ZIP 檔,可是有些壓縮工具(如: 7-zip) 會對內容作排序 , 所以反而造成無法安裝.

2. 如果你不知道什麼是 jar 的話, 最簡單的方法就是去下載 JDK, 然後設定下環境變數 Path. (下載JDK)

)

通常我都會寫一個 批次檔 make_xpi.bat, 把上面的指令放進去, 然後滑鼠 double-clicked!!

所以 makexpi.bat 的相對位置 與產生的 xpi 檔, 展示如下:

snap003

Step 4: 完成

在任意网页使用xpi(zip)文件

測試

Step 1: 測試網頁 test.html

snap003

Step 2: 如果使用者沒安裝你的 plugin, 那長相應該是這樣

snap003

Step 3: 使用者點選那個看起向樂高積木的東西後, Firefox 會到網路上尋找你的 plugin

(因為你還沒上網註冊, 所以一定會找不到的 )

snap003

Step 4: 接下來, 由網頁建議位置下載 剛剛建立好的 xpi 檔

snap003

Step 5: 安裝成功, 點選 Restart Firefox

snap003

接下來 , Extension Manager 會自動管理你的 plug-in

snap003

Step 6: Firefox 正確執行你的 plug-in

snap003

注册xpi(zip)文件

上網註冊你的 Plugins

Step 1: 先到 Firefox 網站註冊

網址: https://addons.mozilla.org/en-US/firefox/users/login?to=en-US%2Ffirefox%2Fbrowse%2Ftype%3A7

snap003

Step 2: 選 Developer Tool

snap003

Step 3: 選左邊的 Submit Add-on

snap003

Step 4: Upload 你的 xpi 檔

snap003

Step 5: 接下來等待核准, 整個處理的流程如下

snap003

詳細說明: https://addons.mozilla.org/zh-TW/firefox/pages/sandbox

Step 6: 檢視放在 Sandbox 的 plugins

snap003

Step 7: 完成

希望對你有幫助!

21May/10

mozilla firefox 插件开发 快速入门

Posted by Nick Xu

如果想讓你的 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 的最新發展, 應該到

http://developer.mozilla.org/en/Plugins

你可以用 plugin 多媒體應用程式, 例如監控系統, 人物自動追蹤 等應用,  全部都可以利用 NPAPI 這個介面讓你的應用程式網頁化.

官方網頁裡面詳細的告訴你,  NPAPI plugins 可以利用 java script 進行操控, 而舊的技術 XPCOMLiveConnect 已經不適合用來開發 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 可以讓你下載, 把所有的檔案下載回去吧!

snap003

注意: 你會在 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-sdkinclude";"C:xulrunner-sdkincludeplugin";"C:xulrunner-sdkincludenspr";"C:xulrunner-sdkincludejava"

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 是否在裡面.

                   長相應該是這樣.

snap003

      Step 3: 執行 測試 test.html

       注意 1: 你下載的 test.html 已經嚴重過期了. 所以我的作法是自己寫一個

       test2.html

文章的例子针对的是Firefox 3.0(貌似用的XULRunner 1.9.0),我电脑上装的Firefox版本为3.5.5,开发用的XULRunner版本为1.9.1.4,发现代码有一些问题,如下所示:

1、npupp.h被npfunctions.h取代了,所以要将npupp.h替换成npfunctions.h。
2、 编译是会提示int16,int32未被定义。首先包含nptypes.h头文件,打开该头文件,发现其中使用了typedef重定义几个简单类型,比如 int16_t,int32_t等。将源代码中所有的int16,int32都替换成int16_t,int32_t。
3、NP_TRUE/NP_FALSE未被定义,直接将其替换成true/false便可。
       修改源代码时不要出现中文,否则编译器会死掉。做到这几点之后编译工程就可以正常生产DLL文件,将nprt.dll拷贝到Firefox安装目录的plugins子目录下,在Firefox的地址栏输入"about:plugins"就可以看到插件了。
       文章中提到Mozilla官方提供的测试页面严重过期,我测试了下还基本正常吧,只不过我下不到作者提供的测试页面,也不知道作者改成什么样子了。测试页 面的代码偏多,它使用embed来嵌入相应类型的东东来调用插件,不知道为什么Firefox依旧显示缺失插件,插件中生成的窗口并没有正确地显示出来, 不过别的部分都是正常的,可以调用foo函数,查看bar属性。
       这个nprt.dll使用nprt.def只向外暴露三个接口,分别是NP_GetEntryPoints、NP_Initialize和 NP_Shutdown,这应该是所有NPAPI插件的规范吧,我是用dumpbin看了看淘宝的Chrome NPAPI插件中npwangwang.dll导出的接口,发现也只有这三个。dll中实现了许多NPP函数,大量的NPN函数都是直接调用NPP函数。 我在代码中加入了许多MessageBox语句以跟踪程序的运行,发现有点头晕。首先NPP_NEW函数会被调用,然后它会生成一个CPlugin对象, 而CPlugin构造函数中又会生成ScriptablePluginObject对象,当关闭测试页面时,相应的对象会被析构,不过有时候有点乱。在脚 本中调用foo函数,会触发ScriptablePluginObject::invoke函数运行,invoke函数内部根据名字实现foo对应的操 作。
bool
ScriptablePluginObject::HasMethod(NPIdentifier name)
{
  return name == sFoo_id;
}
 
bool
ScriptablePluginObject::HasProperty(NPIdentifier name)
{
  return (name == sBar_id ||
          name == sPluginType_id);
}
       这两个函数返回对应的拥有的方法和属性。每次调用方法访问属性时都会调用这两个方法判断相应的方法和属性是否存在。下面给出一个最简单的测试页面,点一个按钮可以调用foo方法,点第二个按钮可以获取bar属性。
<HTML>
<HEAD>
<TITLE>Scriptable Plug-in Test</TITLE>
</HEAD>
<BODY id="bodyId">
 
<object id="pluginobj" type="application/mozilla-npruntime-scriptable-plugin"></object>
 
<br>
<form name="formname">
<input type=button value="Call pluginobj.foo()" onclick='alert(pluginobj.foo())'>
<input type=button value="Get pluginobj.bar" onclick='alert(pluginobj.bar)'>
</form>
 
</BODY>
</HTML>
       呵呵,现在知道怎么做NPAPI插件了,可以为Chrome写一个插件,在右上角的扩展图标栏以一个图标的方式显示电池剩余使用时间,有空的时候就尝试下吧 ^_^
   
site
site