星期四, 11月 30, 2006

修改subversion log訊息

TortoiseSVN有提供修改log訊息的功能:

若你很興奮地改了log訊息想存回,會得到以下回應:
解決方法為:
到subversion repository的hooks目錄中,新增或編輯一個名為pre-revprop-change的檔案,內容改為

#!/bin/sh
exit 0
即可,不過為了安全起見,改完後沒事還是把他還原成不能隨意更動log的狀態比較好

透過reflection取用array元素


for (int idx = 0; idx < myarray.Count; idx++)
{
object item = myarray[idx];
}

如何透過reflection做到上述功能?方法如下:

int count = (int)myarray.GetType().GetProperty("Count").GetValue(myarray, null);
for (int idx = 0; idx < count; idx++)
{
object item = myarray.GetType().GetProperty("Item").GetValue(myarray, new object[] { idx }
);

星期三, 11月 29, 2006

透過reflection機制初始化Field物件

一般來說,初始化Field必須要在定義時做,如:

class TestClass{
private static StringBuilder sb = new StringBuilder();
private static StringBuilder sb2 = new StringBuilder();
}

如果需要三不五時重設這些Field,可能會加上如下的Method:


class TestClass{
private static StringBuilder sb = new StringBuilder();
private static StringBuilder sb2 = new StringBuilder();
public static void ReInit(){
sb = new StringBuilder();
sb2 = new StringBuilder();
}
}

如果之後又有sb3, sb4, ....., sbn,那麼每加一個都得記得去修改ReInit()。不但不方便,還可能忘記。可能的解決方法是利用.NET Reflection機制,查出有哪些Field,然後再根據Field的型別去建立物件。以下範例示範初始化所有static fields (假設所有類別都有不含參數的constructor):


FieldInfo[] fs = typeof(TestClass).GetFields(BindingFlags.Static | BindingFlags.NonPublic);
foreach (FieldInfo f in fs)
{
if (f.IsStatic)
{
object obj = f.FieldType.Assembly.CreateInstance(f.FieldType.FullName);
f.SetValue(null, obj);
}
}

程式範例過大時自動產生捲軸

根據Ove Klykken的Post:
將程式碼用

<div class="scroll">  
void main(.....
</div>

包起來。然後搭配以下CSS:
div.scroll { 
/* height: 200px; 指定高度*/
width: 90%;
overflow: auto;
border: 1px solid #eee;
/* background-color: #ccc; 指定背景顏色*/
padding: 8px;
word-wrap: normal; /* 指定code不要自動換行 */
}

星期二, 11月 28, 2006

CruiseControl中設定程式環境變數

情境:同一個環境變數,但在不同的Project中需有不同的設定
解決方法:撰寫.bat檔案,在裡面設定環境變數

例如

<cruisecontrol>
<project name="MyProject">
<triggers>ooxxooxx</triggers>
<sourcecontrol>ooxxooxx</sourcecontrol>

<tasks>
<msbuild>ooxxooxx</msbuild>

<exec>
<executable>myexec.bat</executable>
</exec>

<nunit>
<path>nunit-console.bat</path>
<assemblies><assembly>ox.dll</assembly></assemblies>
</nunit>
</tasks>

</project>
</cruisecontrol>



其中myexec.bat的內容可能是:
set MyVar=ooxx
myProg.exe


nunit-console.bat的目的則是為了讓unittest時也能夠用對環境變數:
set MyVar=ooxx
C:\oo\pp\xx\nunit-console.exe %1 %2 %3 %4 %5 %6 %7 %8 %9

Visual C++如何決定候選candidate function list

Stan Lippman說明VC++中如何決定candidate function list:
  • Candidate Function List: 在某個呼叫點可視範圍內的所有function中,名稱相同的function所構成的集合
  • 以下例子中,對f(s)這個呼叫點來說,(1)(2)(3)(4)都是candidate function:
    void f(); // (1)
    void f( String^ ); // (2)
    void f( const string& ); // (3)
    void f( String^, array^ ); // (4)

    int main( array ^args )
    {
    if ( args == nullptr )
    handle_invalid_command_line();

    for each ( String^ s in args )
    f( s );
    }
  • 比較特殊的是以下例子,f雖然不在CLITypes namespace中,但因其argument cobj的type在CLITypes namespace中,使得CLITypes::takeC(C^)也列在Candidate Function中:
    namespace CLITypes
    {
    public ref class C {…};
    void takeC( C^ );
    }

    // …

    void f( CLITypes::C^ cobj )
    {
    // ok: calls CLITypes::takeC( C^ )
    takeC( cobj );
    }

星期一, 11月 27, 2006

CruiseControl.NET除錯技巧

CruiseControl Project Break的不明不白時怎麼辦?
打開Build Log,搜尋以下症狀:

  • 「Unhandled Exception:」:執行程式失敗時可能會有此訊息
  • 「success="False"」: Build或Test失敗都會有此訊息

  • 「不是內部或外部命令」:如當使用exec task時可能出現類似以下錯誤訊息
    'OOXX.exe' 不是內部或外部命令、
    可執行的程式或批次檔。


  • 「Assembly not found」: Nunit錯誤訊息

星期日, 11月 26, 2006

如何取得MSN Space內容

設定MSN Space

  1. 確認你的MSN帳號名稱, 假設你的Blog為http://OhOh.spaces.live.com, 則帳號名稱為"OhOh"
  2. 開啟電郵發佈功能
  3. 設定密語

使用MetaWeblog API

  1. 安裝XML-RPC.NET以便使用XML-RPC
  2. AddReference CookComputing.XmlRpcV2.dll
  3. 加入一個新的Class,將以下Code複製進去: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msnspaces/MetaWeblogAPI_CSharp_Code_Sample.asp
  4. using MetaWeblogApi;
  5. 完成:
    MsnSpacesMetaWeblog mw = new MsnSpacesMetaWeblog();
    Post[] ps = mw.getRecentPosts("MyBlog", "OhOh", "ooxxooxx",20);
上述方式最多只能夠在msn space抓到最新的20篇post,如果要抓更多,請參考國良先生在微軟技術社群討論區的文章:
我之前有用C#配合MetaWeblog API寫出一個備份程式,請參考「
Horn Village|牛角村: 【msnSpacesBackup 】利用 MetaWeblog API 來備份 msnSpaces 的網誌」。
要取得所有文章的重點在於postid,若上面那篇文章的URL是...cns!5759F9D78C26191!15004.entry 其中的5759F9D78C26191!15004就是postid,「5759F9D78C26191!」是固定的(但每個人的都不同)而「15004」都是整數而且是越新的文章數值越大,所以要抓全部文章的方法就是從GetRecentPosts取得最新文章的postid(簡單一點就用人工輸入)然後用迴圈遞減postid由GetPost()取得資料。
開站時間越久或文章越多,花費的時間就越多。