1. Fiddler 跟 TFS 相衝的問題解決 - I

    Fiddler, 應該不用我多介紹了, 一套很好用的 Http Debugging Tool. 它的原理是把自己當成 Proxy, 讓所有的 Http 流量都經過它再轉出去, 讓你能看到你的程式到底跟網站講了那些話, 尤其是新興的 AJAX 更需要這種 Tools, 因為一堆東西是你按右鍵 + view source 所看不到的...

    不過以上不是重點, 重點是我常常搭配 visual studio 2005 一起使用, 每當 Fiddler 開啟, 我再使用 vs2005 的 TFS 相關功能時, vs2005 跟 TFS 中間的 http connection 就被欄下來不動了.

     

    Fiddler Log:

    HTTP 401, 看起來就像是 vs2005 傳出去的身份驗證機制沒有成功的通過 Fiddler 傳到 server, 導至 server 回應 401 回報沒有權限... vs2005 回的 ERROR MESSAGE 則是看起來跟這件事一點關聯都沒有...

    正規的解法應該是想辦法讓 vs2005 的驗證能過 Fiddler Proxy ... 不過太懶了, 我發現只要開 Fiddler 等它自動改完 IE Proxy Settings 後再把 TFS 網址加到 bypass host list 後就一切正常了, 所以腦筋就動到怎麼讓 Fidder 自動調整的 Proxy Settings 能自動把 TFS 網址加到忽略清單內. 我打算的流程是這樣:

    1. Fiddler 存下目前的 Proxy Config
    2. Fiddler 把 WinINET 的 Proxy 改為 127.0.0.1:8888
    3. 在 OnAttach 裡加上自定的 Script, 就抄 (2) 的 CODE 改一改再把我要的值加上去

    想的很好, 就開始動工了, 不過開始動工才發現, 原來一路上困難重重... -_-

    << 下期待續 >>

    2007/04/23 .NET Tips 技術隨筆

  2. WMCmd.vbs 在 VISTA 下執行會導至 cscript.exe 發生錯誤...

    我用的冷門工具在 vista 裡又碰到問題了 [:S]

    Windows Media Encoder 9 附的 script: WMCmd.vbs, 在 vista 下執行時, cscript.exe 就會因為 DEP 的原因發生問題, 被攔下來, 看來 Microsoft 自己的 code 也是到處都藏著地雷, 隨便也碰到 data segment 被執行的狀況, 然後 DEP 就啟動了...

    本想把 DEP 關掉了事, 不過 cscript.exe 在 vista 還被限定非得開啟 DEP 不可, Orz, 只好 Google / Microsoft support 查看看有沒有解了. 沒想到運氣還真不錯, 果然在官方網站找到 solution:

     

    FIX: You may experience issues when you use Windows Media Encoder 9 Series on a computer that is running Windows Vista

    URL: http://support.microsoft.com/kb/929182/en-us

     

    果然 FIX 裝了就一切正常, 以前寫的批次轉 video script 繼續用, 剩下只缺 Canon 補上 .CRW 的 codec 了 [:D]

    2007/04/16 Tips 技術隨筆 有的沒的

  3. 手癢亂裝 MyATM...

    最近真是, 裝什麼, 什麼就出問題...

    因為信用卡繳費期限要到了, 換了 Vista 用 WebATM 又有點怪怪的, 其它銀行的都可以, 唯讀台新的 ATM 一連就當, 看到它有 MyATM 這個小工具可以安裝, 就裝起來看看...

    沒想到它只是個很惹人厭的 Applet, 躲在右下角, 等你 ATM 卡片塞進去就跳網頁出來... (這樣的話我幹麻裝... [:@])

    沒想到要移除後, 新增移除工具竟然跟我講權限不足? 搞什麼, Administrators 還沒權限是要怎樣才有權限? 不過這年頭 Error Message 都亂寫一通, 一堆不知道啥怪問題的就說是權限... 讓我想起我追過的一堆 Bug, 都是 try { ... } catch 攔到不知明的 Exception, 就一概顯示 "權限不足, 請聯絡系統管理員" ...

    最好系統管理員真的這麼了不起, 咳咳, 沒事開了 Registry Editor 出來找看看, search "台新銀行", 找到這筆:

    電腦\HKEY_LOCAL\MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{F25E1429-F70A-4843-8885-84CE5E18C352}\UninstallString

    C:\Program Files\\InstallShield Installation Information\{F25E1429-F70A-4843-8885-84CE5E18C352}\setup.exe "-removeonly"

    發現它的路逕怎麼多了一個反斜線? 拿掉之後再移除一次就 OK 了

    真是它ㄨㄨㄨ的... 還好我無聊, 不然安裝程式清單老卡一個不想要的軟體, 看了還真礙眼... 哈哈, 弄完了, 收工!

     

    2007/04/10 Tips 技術隨筆 有的沒的

  4. 原來 System.Net.Mail 也會有 Bug ...

    果然老外寫的程式, 就是容易忽略掉亞洲語系的需求... 為了這個 Bug, 足足浪費我兩天的時間 [:@], 既然糾出來了, 當然要講一下... 先來看這段 sample code:  

    MailMessage mail = new MailMessage();
    Encoding chtEnc = Encoding.GetEncoding(950);
    mail.From = new MailAddress("peter@chicken-house.net", "吳小皮", chtEnc);
    mail.To.Add(new MailAddress("annie@chicken-house.net", "吳小妹", chtEnc));
    mail.Subject = "今天天氣很好";
    mail.SubjectEncoding = chtEnc;
    mail.Body = "blah blah blah...";
    (new SmtpClient()).Send(mail);
    嗯, 執行的很好, 收的到 MAIL, 編碼也沒問題. 不過沒有回應的 code 總是不大 friendly, 加印一行 message 看看...
        MailMessage mail = new MailMessage();
        Encoding chtEnc = Encoding.GetEncoding(950);
        mail.From = new MailAddress("peter@chicken-house.net", "吳小皮", chtEnc);
        mail.To.Add(new MailAddress("annie@chicken-house.net", "吳小妹", chtEnc));
        mail.Subject = "今天天氣很好";
        mail.SubjectEncoding = chtEnc;
        mail.Body = "blah blah blah...";
        Console.WriteLine("準備寄信 (From: {0})", mail.From);
        (new SmtpClient()).Send(mail);
    My God !!! 啥米, 這樣就錯? 而且錯的地方讓我丈二金剛摸不著頭腦... 執行的環境試過 XP, 2003, Vista, 中英文版, 都有 windows update 更新所有的 patch, 除了訊息有中英文版不同之外, 錯誤通通一樣, Exception Dump 如下:
            準備寄信(From: "吳小皮")未處理的例外狀況: System.Net.Mail.SmtpException: 
            傳送郵件失敗。	--->System.FormatException: 
            標頭值中找到無效的字元。	
            於 System.Net.Mime.HeaderCollection.Set(String name, String value)   
                於 System.Net.Mail.Message.PrepareHeaders(Boolean sendEnvelope)   
                於 System.Net.Mail.Message.Send(BaseWriter writer, Boolean sendEnvelope)   
                於 System.Net.Mail.SmtpClient.Send(MailMessage message)
                -- - 內部例外狀況堆疊追蹤的結尾-- - 
                於 System.Net.Mail.SmtpClient.Send(MailMessage message)   
                於 Program.Main()
    真是它ㄨㄨㄨ的, 怎麼會這樣? 我實際的情況比較慘, 是加了一堆 Console.WriteLine( ) 後才突然發現有問題, 跟本搞不清楚怎麼回事... 試到最後, 確定加了 Console.WriteLine( ) 會有問題, 問題是, 這行到底有什麼了不起的? 不過就是 mail.Form.ToString() ... [:|] 決定繼續挖下去, 先從 Exception 開始查. 前面有一大堆不好追的就跳過去了, 從 dump 的 call stack, 再用 Refactor 去反組譯 .net 的 assembly, 最後這裡看起來最像是 Exception 的源頭:
    class: System.Net.Mime.HeaderCollection method: public override void Set(string name, string value)
    截錄片段 source code:
      if (!MimeBasePart.IsAnsi(value, false))
      {
          throw new FormatException(SR.GetString("InvalidHeaderValue"));
      }
    怎麼看都沒問題, 追過 IsAnsi( ), 裡面沒啥特別的 code, 就 char 的值小於 0xff 就判定 pass. 所以問題應該出在 value 的值送進來判定時就已經有問題了... 再往上追, value 的源頭是 MailAddress 物件的 .ToEncodedString( ) 來的:
    class: System.Net.Mail.MailAddress
        internal string ToEncodedString()
        {
            if (this.fullAddress == null)
            {
                if ((this.encodedDisplayName != null) && (this.encodedDisplayName != string.Empty))
                {
                    StringBuilder builder = new StringBuilder();
                    MailBnfHelper.GetDotAtomOrQuotedString(this.encodedDisplayName, builder);
                    builder.Append(" <");
                    builder.Append(this.Address);
                    builder.Append('>');
                    this.fullAddress = builder.ToString();
                }
                else
                {
                    this.fullAddress = this.Address;
                }
            }
            return this.fullAddress;
        }
    然後跟加了就會出問題的 ToString( ) 比對著看:
      public override string ToString()
      {
          if (this.fullAddress == null)
          {
              if ((this.encodedDisplayName != null) && (this.encodedDisplayName != string.Empty))
              {
                  StringBuilder builder = new StringBuilder();
                  builder.Append('"');
                  builder.Append(this.DisplayName);
                  builder.Append("\" <");
                  builder.Append(this.Address);
                  builder.Append('>');
                  this.fullAddress = builder.ToString();
              }
              else
              {
                  this.fullAddress = this.Address;
              }
          }
          return this.fullAddress;
      }
    
    Ouch, 真是想罵人, 問題就在這裡... 看起來是 Microsoft 工程師為了避開重複作編碼的動作, 每次呼叫 ToEncodedString( ) 及 ToString( ) 時都會去看看 fullAddress 這個 private field 是否有值? 有的話代表之前已經作過編碼了, 就直接撿現成. 問題出在第一次呼叫時, 編碼的動作在 ToString( ) 及 ToEncodedString( ) 各寫了一次 (果然沒有做好 refactoring ... 哈哈), 結果 ToString( ) 的這份 code implementation 是錯的, 跟本沒編碼 [:@] ... 我沒事雞婆在寄信前呼叫 ToString( ) 印 Messabe 算我運氣背, 就碰到這個 Bug.. [:@]
    花了近兩天, 不過最後有找到 Bug, 而且還是 Microsoft 的 Bug, 哈哈, 總算證明人不是我殺的 [:D], submit Microsoft 的 Bug 有獎金嘛? 不只 Bug, 連問題都找到了... 有的話通知一下 [:D]

    2007/04/06 .NET Tips 技術隨筆

  5. Canon RAW Codec for Vista 出來了..

    資料來源: http://blogs.msdn.com/pix/archive/2007/03/30/canon-raw-codec-for-vista-release.aspx

    前天才抱怨了一下, WPF 的 WIC 沒有內建 canon raw codec, 沒想到 2007/3/30 已經出來了, 真是失敬 [:p], 不過為什麼只支援 .CR2 啊啊啊啊啊.... 難道用老相機 G2 就註定是這種下場嘛? Orz

    往好方面想, .CRW 的 codec 應該也會出吧? 嗯, 再等一等好了...

    2007/04/04 .NET WPF 技術隨筆 有的沒的