<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
	<title>.Net/Mono</title>
	<link>http://blog.roodo.com/rss20/topic/topic_article_5116.xml</link>
	<description>.Net framework / Mono 的程式設計</description>
	<language>zh-tw</language>
	<generator>Roodo Blog System</generator>
	<copyright>All Rights Reserved</copyright>
	<item>
		<title>boo 的 macro(2) / Thinking more...</title>
		<description>boo 應該是在 0.8 以後吧，就提供了 macro 這個新的關鍵字，用來寫 macro，之前的寫法相當麻煩，需要先繼承 AbstractAstMacro，然後overwrite Expand 這個方法。
新的 macro 關鍵字簡化了一些功夫，macro 之後接的是名稱，下面的 block 就是描述要怎麼去替代，block 的最後再傳回 Ast.Block 即可。

大致的寫法就像這樣子： 
macro Msg:
  args=Msg.Arguments  # macro 名稱其後加上 .Arguments，表示取得 macro 後面的參數
  # [| |] 是相對簡便的語法，表示這裡面是個 Ast.Block，也就是程式區塊，而 .Body 則表示是 macro 下面的 block
  # 注意：[| 後與 |] 前一定要分行，否則會有錯誤
  return [|
    $(Msg.Body)
  |]  
 

寫法相當簡潔，不過在寫的時候，卻很容易讓人碰壁。最大的原因是用法誨澀，以上面的 Msg macro 來說，當 Msg 123 的時候，Msg.Arguments[0] 的型態照理應該是 Int32 才對，但實際上卻是 Ast.IntegerLiteralExpression，型態已經全然是 Compiler AST tree 裡的型態，macro 裡要取用變數、或產生 block也很容易造成困擾，這對於不玩 compiler 的人來說，是相當高的門檻。再者，文件的缺少也是很重要的因素，官方對於這方面的文件非常缺少(比較少人玩 Boo 也是一個主因)。
但是，這對於創造新的語法來說，卻是相當的便利，這也就是一般常說的 DSL，你可以針對某個特定領域來創造適合的語法。網路上能找到的例子，也多半如此。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/10031729.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 23 Sep 2009 15:42:42 +0800</pubDate>
					</item>
	<item>
		<title>boo 的 macro(1) / Thinking more...</title>
		<description>boo 的 macro 跟 C/C++ 的 macro 很類似，都是在編譯時期就被替代為實際的代碼。不過 C/C++ 只做簡單的替換，boo 的 macro 則是會在編譯時期時進行編譯並且執行、進行替換。

 
#
# dontimes.boo
#
import System
import Boo.Lang.Compiler

macro DoNTimes:
    n = DoNTimes.Arguments[0] as Ast.IntegerLiteralExpression
    print n.GetType().ToString() # n is IntegerLiteralExpression
    print DoNTimes.Body.GetType().ToString() # DoNTimes.Body is Block
    blocks = Ast.Block() # create new block add DoNTimes.Body n times.
    for i in range(Convert.ToInt32(n.ValueObject)):
        blocks.Add( DoNTimes.Body )
    return blocks

DoNTimes 3:
    print &quot;foo&quot;

print &quot;Press any key to continue . . . &quot;
Console.ReadKey(true)
 

使用 booi 來執行，你會看到下面的訊息，foo 被印了三次：
 
Boo.Lang.Compiler.Ast.IntegerLiteralExpression
Boo.Lang.Compiler.Ast.Block
foo
foo
foo
Press any key to continue . . .
 
那這跟用 for 迴圈來跑有什麼不同？


首先用 booc 來編譯：booc -t:exe dontimes.boo，在編譯的時候，你會發現第9行跟第10行的訊息被印了出來： 
Boo.Lang.Compiler.Ast.IntegerLiteralExpression
Boo.Lang.Compiler.Ast.Block
 
這證明了 boo compiler 會在編譯時，把 macro 的部份先拿出來編譯，然後在編譯的時後去執行 macro，對程式碼進行替換。然後你會發現執行 dontimes 的時候，只印了 foo 三次。

用  reflector  來看，可以看到：
 
private static void Main(string[] argv)
{
    Console.WriteLine(&quot;foo&quot;);
    Console.WriteLine(&quot;foo&quot;);
    Console.WriteLine(&quot;foo&quot;);
    Console.WriteLine(&quot;Press any key to continue . . . &quot;);
    Console.ReadKey(true);
}
 

代碼只有三行Console.WriteLine(&quot;foo&quot;);，這很清楚的說明了 booc 在編譯時，就把 macro 的內容替換進去了。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/10000813.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 22 Sep 2009 17:36:35 +0800</pubDate>
					</item>
	<item>
		<title>Upgrade Mono to 2.4.2.3 in Ubuntu Jaunty / Thinking more...</title>
		<description>網路上能看到的，多半都是自己編譯 tarball...

  下載  mono in karmic  頁面 File 指示的三個檔案，先解開 mono_2.4.2.3+dfsg.orig.tar.gz，然後切到解開後的目錄下，打上 patch: cat mono_2.4.2.3+dfsg-1.diff.gz | gunzip | patch -p1，再用 chmod +x 幫 debian/rules 加上可執行的屬性。  安裝必要的套件: sudo apt-get install debhelper dpkg-dev libglib2.0-dev bison libtool dpatch libxml-dom-perl libxslt1-dev dc, lsb-release, libx11-dev libxt-dev zlib1g-dev autoconf automake  打開 debian/shlibs.local，把 libsqlite3 後面的  3.6.13 改為 3.6.10，因為 9.04 的 sqlite 是 3.6.10 版。  切到 mono 下，開始 build: cd mono;dpkg-buildpackage  把打包好的 deb 作成 local repository: 假設你把這些 deb 都放到 /opt/mono_debs 下，然後建立 Packages.gz: cd /opt/mono_debs &amp;&amp; dpkg-scanpackages . /dev/null | gzip -9c &amp;gt; Packages.gz。  新增 apt repository:在 /etc/apt/sources.list.d/ 下新增一個 mono.list，裡面放:  deb file:///opt/mono_debs ./ 接下來就可以用 apt-get update、apt-get upgrade 來更新了。  

理論上，這樣就可以更新了，但是事實上，因為 dependency 的關係，apt 會試圖安裝舊的 2.0.1 的 deb 來滿足相依性而導致應用程式有問題。
最好，也循上述的方法，把相關的基底 gtk-sharp2、xsp、gecko-sharp、mono-addins...等套件也重新 build 一次，這樣出現問題的情況應該會減少許多。

我個人建議，要用最新的 mono 還是衝 Karmic (9.10) 吧，這樣會省事很多。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/9976249.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 17 Sep 2009 14:54:39 +0800</pubDate>
					</item>
	<item>
		<title>WebDev.WebServer.exe / Thinking more...</title>
		<description>朋友傳給我幾個 ASP.Net 網頁，是用 3.0/3.5 寫的，懶得用 VWD 2008 開起來看，所以就偷懶用 WebDev.WebServer.exe 來跑，可是卻無法跑起來，會有找不到 System.Linq 的錯誤。原本以為 3.0/3.5 有另一個 WebDev.WebServer.exe，但卻遍尋不著，最後還是用 VWD 2008 開了，當然也能正常執行了。不過我就好奇了，所以用 ProcessExplorer 查了一下，發現我沒錯，的確是用 WebDev.WebServer.exe 執行。再仔細想了一下，才想到，可能是 web.config 裡有鬼，朋友傳給我的檔案裡沒有 web.config，直接執行 WebDev.WebServer.exe ，會使用 .Net 2.0 預設的 web.config。但用 VWD 2008 開過以後，補上了 web.config，裡面有這麼幾行： 
&amp;lt;system.web&amp;gt;
&amp;lt;assemblies&amp;gt;
	&amp;lt;add assembly=&quot;System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089&quot;/&amp;gt;
	&amp;lt;add assembly=&quot;System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089&quot;/&amp;gt;
	&amp;lt;add assembly=&quot;System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;/&amp;gt;
	&amp;lt;add assembly=&quot;System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089&quot;/&amp;gt;
&amp;lt;/assemblies&amp;gt;
&amp;lt;/system.web&amp;gt;
 
一切真相大白，原來是補上了 3.0/3.5 所需的 Assembly，讓 WebDev.WebServer.exe 在跑 3.0/3.5 的 ASP.Net 網頁時沒有問題。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/9536021.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 27 Jul 2009 17:13:59 +0800</pubDate>
					</item>
	<item>
		<title>無法移除的 Powershell v1.0 / Thinking more...</title>
		<description>如果你也跟我一樣，因為要安裝 Powershell v2.0 而無法移除 Powershell v1.0 的話，可以研讀 Powershell team 貼的這篇： Windows PowerShell Blog : Behind PowerShell Installer (for Windows XP / Windows Server 2003): ，了解一下 Powershell 安裝程式做了什麼。不過這篇字太多了，我其實是參考這篇： BUGBUG: poor title » Blog Archive » How to uninstall Powershell v1.0 from Windows Server 2003 R2  來移除的，除了 pwrshsip.dll 無法刪掉之外，基本上不刪掉也沒關係。接著就可以上 Powershell v2.0 CTP3 了。
為什麼要上 Powershell v2.0 CTP3 呢？這是因為 SQL Server 2008 Management Studio Express 的緣故。真是太機車了...
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/9486065.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 20 Jul 2009 01:04:35 +0800</pubDate>
					</item>
	<item>
		<title>Boo Generator expression / Thinking more...</title>
		<description>從這串討論： Array Type Question - Boo Programming Language 裡的例子，最能看出其威力。

objectArray 是一個型別為 object 的陣列，但裡面的 object 其實都是 string。
下面這樣一行，就把型別為 object 的陣列轉為字串的陣列了...

 
strings = array(o as string for o in objectArray)
 

其他更詳細的說明可以參考： 維基教科書 的 BOO/Generators 。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/9406449.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 08 Jul 2009 21:01:14 +0800</pubDate>
					</item>
	<item>
		<title>Mono rpms for CentOS/RHEL 4.x / Thinking more...</title>
		<description>雖然 Mono官方 不再提供 CentOS/RHEL 4.x 的 rpm 了，你還是可以自己重新 build。
在我看過 spec 檔案以後，我發現 Mono 開發團隊已經有加上對 Linux 發行套件的判斷，也就是說其實你可以直接下載 source rpm，安裝必要的函式庫之後，執行 rpmbuild --rebuild xxx.src.rpm 來 build 出 rpm。

source rpms 放在  這裡 。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/9082763.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 27 May 2009 23:50:35 +0800</pubDate>
					</item>
	<item>
		<title>如何在 .Net 調用Yahoo!搜索 斷章取義 API / Thinking more...</title>
		<description>無心工作，剛好又看到有人問怎麼用，所以就牛刀小試一下。基本上用 WebClient 就可以搞定：

 
//
// Yahoo!搜尋『斷章取義』API http://tw.developer.yahoo.com/cas/
// Yahoo!搜尋『斷章取義』API 技術文件 http://tw.developer.yahoo.com/cas/api.php
//
using System;
using System.IO;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;
using System.Text;
using System.Net;

namespace Yahoo
{
    public class CAS
    {
        private string _GetString( byte[] bytes )
        {
            return Encoding.UTF8.GetString(bytes);
        }

        private WebClient GetWebClient()
        {
            WebClient client = new WebClient();
            // client.Proxy = new WebProxy(&quot;localhost&quot;, 8000);
            client.Encoding = Encoding.UTF8;
            return client;
        }

        private NameValueCollection GetParameters()
        {
            NameValueCollection data = new NameValueCollection();

            // TODO: Place your appid here.
            data.Add(&quot;appid&quot;, &quot;APgdNPnV34E7WQlhpBYaQvaRWPjwvd8exe094Q_r_7GWEOBFh9UDQY6vqNgZVwhc&quot;);
            return data;
        }

        public string WordSegmentation(string content)
        {
            NameValueCollection data = GetParameters();
            data.Add(&quot;content&quot;, content);

            WebClient client = GetWebClient();
            byte[] responseArray = client.UploadValues(&quot;http://asia.search.yahooapis.com/cas/v1/ws&quot;, &quot;POST&quot;, data);
            return _GetString(responseArray);
        }

        public string Authenticate()
        {
            NameValueCollection data = GetParameters();

            WebClient client = GetWebClient();
            byte[] responseArray = client.UploadValues(&quot;http://asia.search.yahooapis.com/cas/v1/AuthBootUp.php&quot;, &quot;POST&quot;, data);
            return _GetString(responseArray);
        }

        public string KeywordExtraction( string content, int threshold, int maxnum )
        {
            NameValueCollection data = GetParameters();
            data.Add(&quot;content&quot;, content);
            data.Add(&quot;threshold&quot;, threshold.ToString());
            data.Add(&quot;maxnum&quot;, maxnum.ToString());

            WebClient client = GetWebClient();
            byte[] responseArray = client.UploadValues(&quot;http://asia.search.yahooapis.com/cas/v1/ke&quot;, &quot;POST&quot;, data);
            return _GetString(responseArray);
        }

        public static void Main() 
        {
            Yahoo.CAS cas = new Yahoo.CAS();

            // 如果你重新申請 appid 的話，要先作 Authenticate
            // Console.WriteLine( cas.Authenticate() );
            Console.WriteLine( cas.WordSegmentation( &quot;your_text&quot; ));
            Console.WriteLine( cas.KeywordExtraction( &quot;your_text&quot;, 30, 10));

            // 得到的字串是 XML，要轉為 DataSet 的話，可以這樣作
            /*
            string text = cas.WordSegmentation( &quot;your_text&quot; );
            TextReader stringReader = new StringReader(text);
            DataSet dataSet1 = new DataSet();
            dataSet1.ReadXml(stringReader);
            // 轉好以後應會有兩個 DataTable，資料都在第二個 Table 裡，也就是 dataSet1.Tables[1]
            */
        }
    }
}
 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/8932571.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 13 May 2009 13:37:49 +0800</pubDate>
					</item>
	<item>
		<title>列出 log4net 設定裡所有的 repository 跟 appender / Thinking more...</title>
		<description>Debug 用的，主要是看自己的 log4net 設定對不對。

 
StringBuilder sb = new StringBuilder();
ILoggerRepository[] repos = LogManager.GetAllRepositories();
foreach( ILoggerRepository repo in repos )
{
	sb.AppendLine( &quot;=====&quot; );
	sb.AppendLine( string.Format( &quot;{0} - configured={1}&quot;, repo.Name, repo.Configured.ToString() );
	sb.AppendLine( &quot;Appenders:&quot; );
	foreach( IAppender appender in repo.GetAppenders() )
	{
		sb.AppendLine( string.Format( &quot;\t{0}&quot;, appender.Name ) );
	}
}
sb.AppendLine( &quot;=====&quot; );
Console.WriteLine( sb.ToString() );
 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/7119835.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 05 Sep 2008 16:27:20 +0800</pubDate>
					</item>
	<item>
		<title>booish 與 booc 編譯後的執行結果不同? / Thinking more...</title>
		<description>在 Boo Programming Language網上論壇 發現了這個討論串： Problems with BooPrimer 
發問者表示同樣的程式在 booish 執行與用 booc 編譯後的執行結果不同，我大吃一驚，趕緊試試，發現真的是跟發問者講的一樣，心想完蛋，怎麼會這樣...

 
i = 0
while i  

隔了一天，有人( Stoo )回覆了，說 booish 在執行結束後，會再次印出 i 的值，並建議改成這樣，可以更能看出問題所在：
 
i = 0
while i  

果然，執行結果就如同他回覆所說的一樣： 
i = 0
i = 1
i = 2
i = 3
i = 4
5 
 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/7095965.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 02 Sep 2008 17:35:19 +0800</pubDate>
					</item>
	<item>
		<title>debuan/ubuntu nant-0.85 的 SMP bug / Thinking more...</title>
		<description>最近在  Ubuntu  下用  NAnt  時，有 50% 的機率會遇到類似這樣的錯誤： The current runtime framework &#039;mono-2.0&#039; is not correctly configured in the NAnt configuration file.
    Function call failed.
Expression: ${path::combine(prefix, &#039;lib/mono/1.0&#039;)}
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        Illegal characters in path
Parameter name: path1
 

找了好久，都不知道原因所在，因為有時候是正常執行的。去 Google 試了好幾個關鍵字，都找不到解。今天用 nant &quot;Illegal characters in path&quot; 去找，終於找到了： #483073 - nant: race condition on SMP systems - Debian Bug report logs  
裡面提供的暫時解法是利用環境變數 MONO_NO_SMP，把 SMP 關掉，再執行即可。所以只要編輯 /usr/bin/nant，在 exec 之前加上 export MONO_NO_SMP=1 即可。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6978141.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 25 Aug 2008 14:53:25 +0800</pubDate>
					</item>
	<item>
		<title>最近用 MySql Connector/Net 的幾個心得 / Thinking more...</title>
		<description>  連線字串加上 charset=utf8，如此一來，完全不用更改  MySQL  伺服器設定，只要確定建 database/table 時有指定 utf-8 編碼即可。  SQL 參數在使用 @ 時，若碰到問題，不妨改用 ? 試試。我的確碰到這問題，它卡了我兩、三天，而且改用 ? 也解決了。忘了在哪兒看到，剛好有提到這點，真的是幸好我有看到...   MySQL  有提供 MySqlHelper 類別，省掉寫 Helper 的麻煩...   MySQL  Connector/Net下載網站 上沒有給 Linux 的版本，事實上，是通用的，你可以直接拿給 Mono 用，不需要作任何改動。  
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6898775.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 22 Aug 2008 09:51:23 +0800</pubDate>
					</item>
	<item>
		<title>在 ASP.Net 裡使用 Boo / Thinking more...</title>
		<description>方法很簡單，只要修改 web.config，然後把 Boo 相關的 assembly 放到 bin 目錄下即可： 
&amp;lt;configuration&amp;gt;
	&amp;lt;system.web&amp;gt;
		&amp;lt;compilation debug=&amp;quot;true&amp;quot;&amp;gt;
			&amp;lt;assemblies&amp;gt;          
				&amp;lt;add assembly=&amp;quot;Boo.Lang.CodeDom&amp;quot; /&amp;gt;
			&amp;lt;/assemblies&amp;gt;
			&amp;lt;compilers&amp;gt;
				&amp;lt;compiler language=&amp;quot;Boo&amp;quot; extension=&amp;quot;.boo&amp;quot; type=&amp;quot;Boo.Lang.CodeDom.BooCodeProvider, Boo.Lang.CodeDom&amp;quot; compilerOptions=&amp;quot;-ducky -utf8&amp;quot;/&amp;gt;
			&amp;lt;/compilers&amp;gt;
		&amp;lt;/compilation&amp;gt;
		&amp;lt;customErrors mode=&amp;quot;Off&amp;quot;/&amp;gt;
	&amp;lt;/system.web&amp;gt;
&amp;lt;/configuration&amp;gt;
 

要注意的是，如果你的應用程式不是 code behind 而且 Hosting 是 IIS 或是 .NET framework 內建的小 web server 時，會有問題。問題出在 Indent，Boo 對於 Indent 很敏感，不知道為甚麼，在 Microsoft.NET 下，Indent 就是會錯。使用 Mono XSP 的話，則沒有問題。
是故，你可以改使用 code behind 的方式繞過這問題。

會發現這問題，是因為有人在 boolang 討論群組裡問了這問題： boo on asp.net ，我去試才知道的。最後提問者改用 xsp...
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6859721.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 20 Aug 2008 16:38:49 +0800</pubDate>
					</item>
	<item>
		<title>.NET framework essential Chapter 7/8-ASP.Net/Windows form / Thinking more...</title>
		<description>各自只有一個章節，不過作者很簡明扼要地把該介紹的東西都介紹了。

ASP.Net 除了講 HtmlControl、WebControl 以外，還介紹了 Directive、Session 設定等等。
Windows form 則是簡單的介紹如何開始、Layout 的配置，以及比較容易讓人混淆的 MDI Form。

這本書真的很不錯，講的都很基本，看完對 .NET 會有一定程度的了解，不至於在茫茫大海似的類別庫裡淹死。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6705987.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 08 Aug 2008 09:51:55 +0800</pubDate>
					</item>
	<item>
		<title>App_Offline.htm / Thinking more...</title>
		<description>今天 Trace  Mono  System.Web.HttpRuntime 時看到的，如果在你 ASP.Net 2.0 網站目錄下放置一個 app_offline.htm 時，不管你瀏覽什麼網頁，都只會看到 app_offline.htm 的內容。

詳情可以參考  ScottGu 大  的文章： App_Offline.htm 

很鳥的是，.NET Documentation 裡完全沒提到這個。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6689919.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 07 Aug 2008 14:57:14 +0800</pubDate>
					</item>
	<item>
		<title>Mono 與音訊、視訊 / Thinking more...</title>
		<description> mplayer  的 -input 可以指定 file，man 裡面說明了你可以給一個 FIFO 的檔案。
藉著這個，於是就可以寫程式來控制  mplayer  來播放影片或是音樂。
你可以參考 致遠管理學院資工系專題研究計畫研究成果報告計畫： Linux C# 設計 ... 

你還可以使用  GStreamer# ， Mono  team 的人已經幫你將  gstreamer  函式庫包裝為  GStreamer# ，因此使用  GStreamer#  也可以進行播放影片和音樂，最好的例子是  Banshee 。
不過這只適用於 Linux。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6658157.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 05 Aug 2008 17:49:15 +0800</pubDate>
					</item>
	<item>
		<title>.NET framework essential Chapter 6-Web Services / Thinking more...</title>
		<description>最前面是一堆有點誇張的介紹，不過在當時大家真的都以為 Web Services 很棒...
這一章介紹 Web Services 的觀念與實作，由於微軟是規格制定者，所以 .NET 對 Web Services 的支援不能少，下了很多功夫。
主角是 WebService 類別與 WebMethodAttribute，方法是繼承 WebService 類別，然後在要被呼叫的方法上，標上 WebMethod attribute。

以前以為 Web Services 的底層是 SOAP，所以只能用 SOAP，沒想到也可以用 GET/POST 的方式來呼叫，所以 javascript 也能輕易地呼叫 Web Services，然後解析回傳的 XML 即可。
Security 方面，以前也以為沒有 session，現在也知道可以用了。另外還介紹了兩種層級的保護，系統層級是利用 IIS 管理介面設定權限與 SSL 來達成，Application Level，則是利用 .NET 的 web.config 來達成。
SSL 對於 Web Service 來說，是個稍嫌沈重的負擔，所以他也建議使用 authentication token 的方式，也就是提供一個架構在 SSL 上，可以取得 authentication token 的方法，取得 token 之後，後續的呼叫都要帶入這個 token，以作為識別。
這樣的方式，在目前有提供 Open API 的網站上很常見。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6638049.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 01 Aug 2008 13:33:47 +0800</pubDate>
					</item>
	<item>
		<title>MonoDevelop on Windows / Thinking more...</title>
		<description> Cygwin  要裝些什麼可以參考這篇： CodeProject 上的文章：Building Mono on Windows: the final battle.  
不過  Mono  可以直接用官方提供的，不需要自己 build。 
 
首先進  Cygwin  shell，設定 PATH 與 PKG_CONFIG_PATH，讓  Cygwin  能找到  Mono ：
 export PATH=/cygdrive/c/Progra~1/Mono-1.9.1/bin:$PATH
export PKG_CONFIG_PATH=/usr/lib/pkgconfig/:/usr/local/lib/pkgconfig/:/cygdrive/c/Progra~1/Mono-1.9.1/lib/pkgconfig 
 
再把  Mono  目錄下的 pkg-config 更名，因為這個版本的 pkg-config 太舊。 
 
接著要 build Mono-Addin-0.3.1，這簡單，很快就 build 過了。(./configure &amp;&amp; make &amp;&amp; make install ) 
 
再來就麻煩了，1.0 無法 build，它會要求裝 monodoc, gtksourceview-sharp-2.0.0；monodoc 其實已經有了，但卻沒有給 pkg-config 用的 .pc 檔，所以補上一個自製的 monodoc.pc。接著，gtksourceview-sharp 則需要裝 gnome-sharp、gtk-sharp 與實體的 gtk+、gnome 函式庫，所以我放棄 1.0，改用 1.9。1.9 是比較順利了，順利的原因是， MonoDevelop  team 本來就有打算要出 Windows 版本，只是能不能用還在未知之數。 
 
在 build 的過程中，發現 gmcs 無法載入 Mono.Addin.Setup assembly 的問題，這是由於 gacutil 跟  Cygwin  相處的不太好，gacutil 收的 path separator 是反斜線 &#039;\&#039;，但  Cygwin  只能給 &#039;/&#039;，所以安裝 Mono.Addin 時，並沒有依照 Makefile 的指定，將 .dll 註冊到 gac 所以在編譯(make)、安裝(make install)後，你必須要手動將 .dll 註冊到 gac 裡： cd bin;find . -name &#039;*.dll&#039; -exec gacutil -i {} \; 
 
接著， MonoDevelop  就 build 成功了。不過， MonoDevelop  還是不能執行 :-( MonoDevelop.Core.Gui.Services 這邊會丟出例外。 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6634735.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 31 Jul 2008 20:06:16 +0800</pubDate>
					</item>
	<item>
		<title>Banshee 的 PlayQueue / Thinking more...</title>
		<description>1.0 版以後多了一個新功能-PlayQueue，我很喜歡這功能，因為你可以一直把想聽的歌丟進去， Banshee 會播放這個Queue裡的歌直到Queue沒有歌為止。
本來以為這是內建的功能，後來看了之後，才發現這是一個 Extension。
它主要繼承 PlaylistSource、IBasicPlaybackController，把自己實作成一個 Playlist 來源，在 Banshee 播放時，實際上來源已經不是原來的 Music library 了。

所以如果要取得這個 Source，應該是利用 ServiceManager.SourceManager 來取得，要加入 PlayQueue 的話，則是使用 AddSelectedTracks()。
目前我還沒研究出如何在 Extension 裡面 呼叫 其他 Extension 的方法...
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6544067.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 23 Jul 2008 08:42:57 +0800</pubDate>
					</item>
	<item>
		<title>讓 Banshee 啟動時自動播放音樂之二 / Thinking more...</title>
		<description>每次都從第一首播放，實在太沒意思，所以在播放前切換為 Shuffle 模式，播放時，就會隨機挑選一首開始播放，然後再關閉 Shuffle 模式。

 
import System
import System.IO
import Banshee.ServiceStack
import Banshee.PlaybackController

def AutoPlay() as bool:
        ServiceManager.PlaybackController.ShuffleMode = PlaybackShuffleMode.Song
        ServiceManager.PlayerEngine.Play()
        ServiceManager.PlaybackController.ShuffleMode = PlaybackShuffleMode.Linear

def OnClientStarted( client as Client ):
        Hyena.Log.Information( &quot;engine is playing now...&quot; )
        GLib.Timeout.Add(1500, AutoPlay)
        Banshee.ServiceStack.Application.ClientStarted -= OnClientStarted

Hyena.Log.Information( &quot;autoplay script is loaded.&quot; )

Banshee.ServiceStack.Application.ClientStarted += OnClientStarted
 

p.s. 上次有提到要作自動記錄播放與自動播放記錄曲目的功能，我的確是做了，只是在播放完指定曲目後，又跳回第一首，這表示我還得繼續研究原始碼才行，所以暫時不釋出。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6540335.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 22 Jul 2008 09:39:14 +0800</pubDate>
					</item>
	<item>
		<title>.NET framework essential Chapter 5 / Thinking more...</title>
		<description>這一章主要講 ADO.Net。
DataSet、DataTable、DataRow、DataRelation... 這一組類別完全是一個抽離實體層的類別，所以有 DataAdapter 這一組與 Connection、Command、DataReader ...等類別溝通。

  GetChildRows[] 可以依據 Relationship 來取得子Table與父Table相關的資料列。  一個 DataAdapter 基本上對應一個 DataTable，但他不管所在的 DataSet，所以你可以都塞到同一個 DataSet 裡面去。另外 DataAdapter 不處理 Relationship，所以用 Fill 取得資料並放到 DataSet 裡的 DataTable 之後，得自己加上 Relationship。  由於 DataSet 與 XML 有一定的關係，第五章最後簡單地介紹了 XML 的相關函數。  
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6536721.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 21 Jul 2008 13:16:58 +0800</pubDate>
					</item>
	<item>
		<title>用 Boo 寫 Web Service / Thinking more...</title>
		<description>必須先將以 Boo 寫的 Web Service 編譯為 Assembly，然後再製作一個以 c# 或 vb.net 寫的 asmx 繼承該 Web Service 類別才行。
否則會遇到 &quot;The invoked member is not supported in a dynamic module.&quot; 的錯誤。

我是在遇到錯誤的時候，去參考 boo 源碼 examples/asp.net 下的 Math.asmx 與 Math.asmx.boo 才知道這件事情的。
本來我還在納悶，為甚麼 examples/asp.net 下會有一個用 c# 寫的 asmx，還以為是搞錯了呢～

 
// Math.asmx.boo
// 要先編譯好，放在 bin 目錄下：booc -t:library -out:bin/Math.dll Math.asmx.boo
import System.Web.Services

[WebService]
class Math:
        [WebMethod]
        def Add(a as int, b as int):
                return a+b

        [WebMethod]
        def Multiply(a as int, b as int):
                return a*b
 

 
&amp;lt;%@WebService Class=&quot;MathService&quot; Language=&quot;C#&quot; %&amp;gt;
// Math.asmx
public class MathService : Math  // 繼承用 Boo 寫的 Math 類別
{
}
 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6506341.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 15 Jul 2008 14:08:11 +0800</pubDate>
					</item>
	<item>
		<title>讓 Banshee 啟動時自動播放音樂 / Thinking more...</title>
		<description>主要是利用上一篇介紹的 BooScript Extension，讓  Banshee  能在一開始就播放音樂... 
BooScript Extension 在載入時，會檢查是否有 script 要執行，有的話，會進行編譯並執行，所以這個時候  Banshee  內部還有許多事情還沒初始完成，所以必須要將 AutoPlay 的動作排程到 Application.ClientStarted 裡，讓 Application 啟動之後去執行 AutoPlay 的動作。 

 
import System
import System.IO
import Banshee.ServiceStack

def OnClientStarted( client as Client ):
	Hyena.Log.Information( &quot;engine is playing now...&quot; )
	ServiceManager.PlayerEngine.Play()

Hyena.Log.Information( &quot;autoplay script is loaded.&quot; )

Banshee.ServiceStack.Application.ClientStarted += OnClientStarted
 

就這麼簡單，下次要加上自動記錄播放與自動播放記錄曲目的功能。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6319131.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 04 Jul 2008 10:09:28 +0800</pubDate>
					</item>
	<item>
		<title>.NET framework essential Chapter 4 / Thinking more...</title>
		<description>Chapter 3 主要是講各種語言的介紹與互相操作，大致都已經知道，沒什麼要紀錄的。
接著記 Chapter 4 的一些東西。

  只要在 .config 裡面使用 bindingRedirect，就可以重新導向相依的assembly到新版本的assembly。.config 裡的 attribute：runtime / assemblyBinding / dependentAssembly  Remoting object 的程式真的出乎意料地簡單，以前從沒研究過，有機會來試試效能，看看傳一堆物件或是 Dataset 的效能如何。  有一個 Attribute 的簡單範例...  支援 Transaction 的要件：  繼承 ServicedComponent  使用正確的 Transaction attribute  接著就可用 System.EnterpriseServices.ContextUtil。此外最好也指定 ApplicationName、ApplicationActivation 等組件attribute。.NET 會在編譯時自動把組件加入 COM+ Service 裡，無須自己動手註冊。這邊還有 Object pooling、Role base、Message Queuing 的例子，很淺顯易懂。這部份在 Mono 裡都沒有被實作出來，主要是因為 COM+ 在 Linux 下沒有替代品的關係。  
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6298417.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 03 Jul 2008 16:55:47 +0800</pubDate>
					</item>
	<item>
		<title>在 Banshee 1.0 裡使用 BooScript / Thinking more...</title>
		<description>有兩種方法：  執行 Banshee 時，加上 --run-scripts your_boo_scripts.boo 表示要執行指定的 boo script  將 boo script 檔案放在 ~/.config/banshee-1/boo-scripts/  

如果你會  Boo  的話，基本上就不難幫  Banshee  增加功能。不過難就難在你必須要對  Banshee  的原始碼有一定程度的了解...除了看原始碼以外，也可以看看官方提供的 extension 怎麼寫...
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6293803.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 03 Jul 2008 14:06:22 +0800</pubDate>
					</item>
	<item>
		<title>Boo(20)-Generator 函式 / Thinking more...</title>
		<description>Generator 函式其實就跟 C# 的 Iterator 一樣，利用 yield 關鍵字先把值傳回讓呼叫者使用。
使用 Generator/Iterator 最大的好處是可以讓函式只做必要的邏輯，而不需要把一些事情綁在迴圈裡面。
下面就是一個很標準的尋訪目錄樹的範例，尋訪的工作交給 walk，主程式則負責依據傳回的值作處理。

 
import System
import System.IO

def walk( path as string ):
  di = DirectoryInfo( path )
  for d in di.GetDirectories():
    yield d as FileSystemInfo
  for f in di.GetFiles():
    yield f as FileSystemInfo

for node in walk( &quot;.&quot; ):
  if node isa DirectoryInfo:
    print &quot;[${node.Name}]&quot;
  elif node isa FileInfo:
    print node.Name
 

參考自： Generators 

p.s. 這系列文章一定會持續寫到 macro 出現為止。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6236271.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 27 Jun 2008 14:08:30 +0800</pubDate>
					</item>
	<item>
		<title>.NET essential 第二章 CLR 筆記 / Thinking more...</title>
		<description>主要是紀錄以前不知道或是看過沒深入了解的一些東西：  Managed C++ 編譯出來的執行檔無法用 mono 執行，可能是因為 Native code 跟 IL code 放到一起的關係。  從 stack-based 的 value type 轉成 heap-based 的 reference type 的過程稱作 boxing，反之稱作 unboxing。 int i=1;
object obj = i; // boxing
int j = (int)obj; // unboxing
   為了要讓各種語言能在 CLR 上執行，有 Common Language Specification 的 ECMA 標準 -  Standard ECMA-335 。  NGen 可以預先將 IL code 轉為 Native executable code，省掉 JIT compiler 的工作(pre-JITting)，因此可以加速。 mono 裡似乎是用  mono -O=all --aot your-assembly  來替代的樣子。  
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6217521.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 23 Jun 2008 11:24:43 +0800</pubDate>
					</item>
	<item>
		<title>Boo 的 currying / Thinking more...</title>
		<description>拜讀了 Jserv大的&quot;以 C 語言實做 Functional Language 的 Currying&quot; 與 Thinker大的&quot;真 C 語言實做 Functional Language 的 Currying&quot; 以後，決定也來挖掘一下  Boo  的 currying 寫法，根據這篇文章： Boo Programming Language Languages Currying Def Return World ，程式碼出乎意料的簡單：
 
//Currying:
plusX = { a as int | return { b as int | return a + b }}

print plusX(3)(4) 
 
就這樣。老實說，大概懂了，可是又不是很懂，也沒想到用途。

所以，就跟沒懂是一樣的。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6206869.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 20 Jun 2008 19:20:36 +0800</pubDate>
					</item>
	<item>
		<title>Boo(19)-例外處理 / Thinking more...</title>
		<description>例外處理的語法與 Python 相近，差別在於 Boo 使用 ensure，而 Python 使用 finally。 
除此之外，Boo 統一使用 except 處理各種例外，而 Python 使用 else 處理無法處理的例外型態。 

 
import System

class MyException(Exception):
  _msg as string
  def constructor( s as string ):
    _msg = s
  override def ToString() as string:
    return &quot;MyException::${_msg}&quot;

// 試著調整這兩個變數試試看
isExceptionHappen = false
isMyExceptionHappen = true

try:
  // .. do something ...
  if isExceptionHappen:
    raise Exception(&quot;Something wrong.&quot;)  // 提出例外情況
  // ...
  if isMyExceptionHappen:
    raise MyException(&quot;Hey!!&quot;)
except e as MyException:
  print e.ToString()
except e as Exception:
  print e.Message
ensure:
  print &quot;不管有沒有錯誤，這裡都會被執行。&quot;
 

參考： Boo Primer - 例外 、 Python tutorial - 8. Errors and Exceptions 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6183075.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 16 Jun 2008 17:29:18 +0800</pubDate>
					</item>
	<item>
		<title>Boo(18)-命名空間 / Thinking more...</title>
		<description>.NET上的語言幾乎都導入命名空間了，Boo 無法置身事外... 
 
命名的方式，則是在原始檔第一行加上： namespace 命名空間名稱 
撇開註解不算，命名空間的宣告，無論如何都要是程式碼的第一行，否則會有錯誤發生。 
 
引用時，則是使用 import 關鍵字，例如： 
import System

Console.WriteLine( &quot;Hello world!&quot; )

// 為甚麼要引用命名空間？因為這樣寫很累...
System.Console.WriteLine( &quot;Hello again.&quot; )
 

你也可以指明組件(Assembly)的名稱，所以這幾種寫法也行： 
import System.Data from System.Data
import Gtk from &quot;gtk-sharp&quot;
 
 
對了，組件不需要特別加上 &quot;.dll&quot; 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6172525.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 13 Jun 2008 16:47:29 +0800</pubDate>
					</item>
	<item>
		<title>Boo(17)-結構與列舉 / Thinking more...</title>
		<description>結構(struct)跟類別很類似，最明顯的差別在於 class 被換成 struct 了，類別的一些特性也可以在結構上使用。
其他的差別：無法繼承類別、結構，只能實作 Interface﹔結構是值型別，在複製實體時，是整個克隆(Clone)而不是像類別一樣，只做參考。
 
struct Dog:
  def constructor( name ):
    _name=name
  [property(Name)]
  _name as string
emptydog=Dog()
print &quot;emptydog.Name=${emptydog.Name}&quot;  // 什麼都沒印出
lucky=Dog(&quot;Lucky&quot;)
print &quot;lucky.Name=${lucky.Name}&quot;  // 印出 Lucky
 

列舉(enum)，如果你有用過 C/C++/C# 的話，應該不陌生：
 
// 宣告列舉
enum Day:
    Sunday
    Monday
    Tuesday
    Wednesday
    Thursday
    Friday
    Sunday
// 也可以指定數值
enum Task:
    TODO=100
    FIXME=101
// 列印
print Day.Sunday
// 尋訪列舉型別裡所有元素
for s in Enum.GetNames(Day):
    print s
// 另一種
for n,v in array( zip( Enum.GetNames(Task), Enum.GetValues(Task)) ):
    print &quot;${n}=${v}&quot;
 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6140389.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 06 Jun 2008 14:21:53 +0800</pubDate>
					</item>
	<item>
		<title>Boo(16)-Class / Thinking more...</title>
		<description>Boo 的類別(Class)，跟 Python 很像，基本上不複雜。
 
class Animal:
  pass

class Dog(Animal):
  def constructor():
    pass
  def constructor( name ):
    _name=name
  def destructor():
    pass
  def Bark():
    print &quot;${_name} is barking...&quot;
  [property(Name)]
  _name = &quot;Anonymous&quot;
spot=Dog( &quot;spot&quot; )
whity=Dog( Name:&quot;whity&quot; )
print spot.Name
whity.Bark()
 
 
class 跟 C# 一樣，可以加上 public、protected、internal、protected internal、private、abstract、final 等修飾詞，預設是 public。 
繼承的話，就是在類別名稱後面加上小括號，並在括號內放置欲繼承的類別。 
建構子與解構子分別是 constructor 與 destructor，可寫可不寫。 
方法的宣告其實跟前面提到的函數很像，都是使用 def ，def 的前面還可以加上 abstract、static、virtual、override 等修飾詞。 
最後是欄位，通常就跟寫運算式一樣，給定一個值就行了，像這樣：_name=&quot;&quot;，前面的 [property()] 是 attribute，是一個偷懶的寫法，實際上是 get/set 的組合體：
 
class Cat(Animal):
  def constructor():
    pass
  def constructor( name ):
    _name=name
  def destructor():
    pass
  def Meow():
    print &quot;${_name} is meowing...&quot;
  Name as string:
    get:
      return _name
    set:
      _name=value
  _name = &quot;Anonymous&quot;
 
 
看到這裡，你有發現到這行嗎？whity=Dog( Name:&quot;whity&quot; )。咦，莫非在建構時可以直接指定屬性的值，沒錯，這寫起程式來方便很多啊～ 
 
參考資料：   Boo Primer - 類別    Boo Primer - 方法    Boo Primer - 多型與繼承   
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6122051.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 02 Jun 2008 15:34:28 +0800</pubDate>
					</item>
	<item>
		<title>Boo(15)-內建函數：容器操作 / Thinking more...</title>
		<description>join()、map()、array()、matrix()、iterator()、enumerate()、range()、reversed()、zip()、cat()

這一類的函式還...蠻多的，大多都與 python 相容。

join()，把 Enumerator 裡面每個元素轉成字串，最後串成一個字串傳回。你也可以加上第二個引數，他會自動幫你加上，例如：join( [1,2,3,4,5], &quot;:&quot; ) 會得到 &quot;1:2:3:4:5&quot; 的字串。
map()，對 Enumerator 裡面每個元素施行指定的函式。
array()，傳入一個 Enumerator 回傳一個陣列。
matrix()，建立多維陣列。
iterator()，取得物件的 IEnumerable 介面，如果物件沒有 IEnumerable 介面，但有繼承 TextReader 的話，則改用 TextReaderEnumerator.lines() 取得 IEnumerable。這個函數在內部非常頻繁地被這裡提到的其他函數使用到。
enumerate()，先取得物件的 IEnumerable 介面，然後傳回類似 (index, value ) 的 Enumerator，舉例來說，List( enumerate( [ &quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot; ] ) ) 的結果會是：[(0, &#039;a&#039;), (1, &#039;b&#039;), (2, &#039;c&#039;), (3, &#039;d&#039;)]。
range() 很容易理解，傳入數值，會回傳有循序數值的 Enumerator，你也可以傳入起始與結束的數值或是傳入起始、結束與遞增數。
reversed()，將 Enumerator 裡面的元素以相反順序擺放，內部是使用 ReversedListEnumerator 類別來完成這件事情。
zip()，傳入多個 Enumerator，它會把每個 Enumerator 的第 0 個元素放到一起、第 1 個元素放到一起...以此類推，最後再傳回一個 Enumerator。這個函數看例子會比較容易了解，array(zip([&#039;a&#039;,&#039;b&#039;,&#039;c&#039;],[4,5,6],[&#039;aa&#039;,&#039;bb&#039;,&#039;cc&#039;])) 的結果會是 ((&#039;a&#039;, 4, &#039;aa&#039;), (&#039;b&#039;, 5, &#039;bb&#039;), (&#039;c&#039;, 6, &#039;cc&#039;))。老實說，我還沒想到要怎麼用...
cat()，跟 join 有點像，不過不會傳回字串，而是把傳入的 Enumerator 串接起來成一個 Enumerator 再傳回。

這裡有的函數我沒舉例，要看例子的話，可以參考 Boo Primer中文版對內建函數的說明 。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6106269.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 29 May 2008 13:49:50 +0800</pubDate>
					</item>
	<item>
		<title>Boo(14)-內建函數：輸入與輸入 / Thinking more...</title>
		<description>print、gets、prompt 
 
print 就是調用 Console.WriteLine() 而已，官方建議使用 print macro，而不要使用這個函數。 
gets 從標準輸入取得一個字串，實際上就是調用 Console.ReadLine()。 
prompt 是 Console.ReadLine() + Console.Write() 的組合技，在印出你給的提示訊息之後，會接著從標準輸入取得字串。 
 
從標準輸入取得字串的意思就是，畫面會停住，等你輸入字元，直到你按下 Enter 之後，才把你輸入的字元放到字串裡傳回。 
 
 
print(&quot;Hello&quot;)
s = gets()
print s
s = prompt(&quot;Please input something:&quot;)
print s
 
 
當然，除了這些函數以外，你還是可以直接使用 .NET Framework 裡的 System.IO 來處理。 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6070927.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 23 May 2008 09:48:06 +0800</pubDate>
					</item>
	<item>
		<title>Boo(13)-內建函數：shell 類 / Thinking more...</title>
		<description>shell()、shellp()、shellm()  
顧名思義，就是執行外部的程式。 
 
shell() 會等待外部程式執行完成以後，回傳一個字串，字串裡是執行的結果。 
shellp() 不會等待外部程式執行完成，會直接回傳 Process 物件，事實上，shell() 也呼叫了這個函數，只是 shell() 拿到 Process 物件以後，利用 Process.StandardOutput() 去讀取執行結果，並使用 Process.WaitForExit() 等待程序執行完成。 
shellm() 也是執行外部程式，但這個外部程式必須是 Managed，也就是 .NET 應用程式。老實說，看了 boo 源碼以後，我不是很懂。源碼裡面是建立一個新的 AppDomain，載入指定的程式，然後找到 EntryPoint 並執行。我猜想，這樣的作法主要用來避免再次建立新程序、啟動 CLR，在 CPU、記憶體使用上會比較有效率。如果你的外部程式正好也是 .NET 應用程式的話，就用 shellm()，我想會比較好。 

 
input = shell( &quot;booc.exe&quot;, &quot;&quot; )
 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6059285.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 21 May 2008 14:31:33 +0800</pubDate>
					</item>
	<item>
		<title>booc 的 49 道工法 / Thinking more...</title>
		<description>從 Visual Studio debugger 裡面截出來的...想不到編譯需要這麼多步驟...
 
-		_items	{維度:[64]}	object[]
+		[0]	{Boo.Lang.Parser.BooParsingStep}	object {Boo.Lang.Parser.BooParsingStep}
+		[1]	{Boo.Lang.Compiler.Steps.InitializeTypeSystemServices}	object {Boo.Lang.Compiler.Steps.InitializeTypeSystemServices}
+		[2]	{Boo.Lang.Compiler.Steps.PreErrorChecking}	object {Boo.Lang.Compiler.Steps.PreErrorChecking}
+		[3]	{Boo.Lang.Compiler.Steps.ExpandAstLiterals}	object {Boo.Lang.Compiler.Steps.ExpandAstLiterals}
+		[4]	{Boo.Lang.Compiler.Steps.MergePartialClasses}	object {Boo.Lang.Compiler.Steps.MergePartialClasses}
+		[5]	{Boo.Lang.Compiler.Steps.InitializeNameResolutionService}	object {Boo.Lang.Compiler.Steps.InitializeNameResolutionService}
+		[6]	{Boo.Lang.Compiler.Steps.IntroduceGlobalNamespaces}	object {Boo.Lang.Compiler.Steps.IntroduceGlobalNamespaces}
+		[7]	{Boo.Lang.Compiler.Steps.TransformCallableDefinitions}	object {Boo.Lang.Compiler.Steps.TransformCallableDefinitions}
+		[8]	{Boo.Lang.Compiler.Steps.BindTypeDefinitions}	object {Boo.Lang.Compiler.Steps.BindTypeDefinitions}
+		[9]	{Boo.Lang.Compiler.Steps.BindGenericParameters}	object {Boo.Lang.Compiler.Steps.BindGenericParameters}
+		[10]	{Boo.Lang.Compiler.Steps.BindNamespaces}	object {Boo.Lang.Compiler.Steps.BindNamespaces}
+		[11]	{Boo.Lang.Compiler.Steps.BindBaseTypes}	object {Boo.Lang.Compiler.Steps.BindBaseTypes}
+		[12]	{Boo.Lang.Compiler.Steps.BindAndApplyAttributes}	object {Boo.Lang.Compiler.Steps.BindAndApplyAttributes}
+		[13]	{Boo.Lang.Compiler.Steps.ExpandMacros}	object {Boo.Lang.Compiler.Steps.ExpandMacros}
+		[14]	{Boo.Lang.Compiler.Steps.IntroduceModuleClasses}	object {Boo.Lang.Compiler.Steps.IntroduceModuleClasses}
+		[15]	{Boo.Lang.Compiler.Steps.NormalizeStatementModifiers}	object {Boo.Lang.Compiler.Steps.NormalizeStatementModifiers}
+		[16]	{Boo.Lang.Compiler.Steps.NormalizeTypeAndMemberDefinitions}	object {Boo.Lang.Compiler.Steps.NormalizeTypeAndMemberDefinitions}
+		[17]	{Boo.Lang.Compiler.Steps.BindTypeDefinitions}	object {Boo.Lang.Compiler.Steps.BindTypeDefinitions}
+		[18]	{Boo.Lang.Compiler.Steps.BindGenericParameters}	object {Boo.Lang.Compiler.Steps.BindGenericParameters}
+		[19]	{Boo.Lang.Compiler.Steps.BindEnumMembers}	object {Boo.Lang.Compiler.Steps.BindEnumMembers}
+		[20]	{Boo.Lang.Compiler.Steps.BindBaseTypes}	object {Boo.Lang.Compiler.Steps.BindBaseTypes}
+		[21]	{Boo.Lang.Compiler.Steps.BindMethods}	object {Boo.Lang.Compiler.Steps.BindMethods}
+		[22]	{Boo.Lang.Compiler.Steps.ResolveTypeReferences}	object {Boo.Lang.Compiler.Steps.ResolveTypeReferences}
+		[23]	{Boo.Lang.Compiler.Steps.BindTypeMembers}	object {Boo.Lang.Compiler.Steps.BindTypeMembers}
+		[24]	{Boo.Lang.Compiler.Steps.ProcessInheritedAbstractMembers}	object {Boo.Lang.Compiler.Steps.ProcessInheritedAbstractMembers}
+		[25]	{Boo.Lang.Compiler.Steps.CheckMemberNames}	object {Boo.Lang.Compiler.Steps.CheckMemberNames}
+		[26]	{Boo.Lang.Compiler.Steps.ProcessMethodBodiesWithDuckTyping}	object {Boo.Lang.Compiler.Steps.ProcessMethodBodiesWithDuckTyping}
+		[27]	{Boo.Lang.Compiler.Steps.PreProcessExtensionMethods}	object {Boo.Lang.Compiler.Steps.PreProcessExtensionMethods}
+		[28]	{Boo.Lang.Compiler.Steps.UnfoldConstants}	object {Boo.Lang.Compiler.Steps.UnfoldConstants}
+		[29]	{Boo.Lang.Compiler.Steps.OptimizeIterationStatements}	object {Boo.Lang.Compiler.Steps.OptimizeIterationStatements}
+		[30]	{Boo.Lang.Compiler.Steps.BranchChecking}	object {Boo.Lang.Compiler.Steps.BranchChecking}
+		[31]	{Boo.Lang.Compiler.Steps.CheckIdentifiers}	object {Boo.Lang.Compiler.Steps.CheckIdentifiers}
+		[32]	{Boo.Lang.Compiler.Steps.StricterErrorChecking}	object {Boo.Lang.Compiler.Steps.StricterErrorChecking}
+		[33]	{Boo.Lang.Compiler.Steps.CheckAttributesUsage}	object {Boo.Lang.Compiler.Steps.CheckAttributesUsage}
+		[34]	{Boo.Lang.Compiler.Steps.ExpandDuckTypedExpressions}	object {Boo.Lang.Compiler.Steps.ExpandDuckTypedExpressions}
+		[35]	{Boo.Lang.Compiler.Steps.ProcessAssignmentsToValueTypeMembers}	object {Boo.Lang.Compiler.Steps.ProcessAssignmentsToValueTypeMembers}
+		[36]	{Boo.Lang.Compiler.Steps.ExpandProperties}	object {Boo.Lang.Compiler.Steps.ExpandProperties}
+		[37]	{Boo.Lang.Compiler.Steps.RemoveDeadCode}	object {Boo.Lang.Compiler.Steps.RemoveDeadCode}
+		[38]	{Boo.Lang.Compiler.Steps.CheckMembersProtectionLevel}	object {Boo.Lang.Compiler.Steps.CheckMembersProtectionLevel}
+		[39]	{Boo.Lang.Compiler.Steps.NormalizeIterationStatements}	object {Boo.Lang.Compiler.Steps.NormalizeIterationStatements}
+		[40]	{Boo.Lang.Compiler.Steps.ProcessSharedLocals}	object {Boo.Lang.Compiler.Steps.ProcessSharedLocals}
+		[41]	{Boo.Lang.Compiler.Steps.ProcessClosures}	object {Boo.Lang.Compiler.Steps.ProcessClosures}
+		[42]	{Boo.Lang.Compiler.Steps.ProcessGenerators}	object {Boo.Lang.Compiler.Steps.ProcessGenerators}
+		[43]	{Boo.Lang.Compiler.Steps.ExpandVarArgsMethodInvocations}	object {Boo.Lang.Compiler.Steps.ExpandVarArgsMethodInvocations}
+		[44]	{Boo.Lang.Compiler.Steps.InjectCallableConversions}	object {Boo.Lang.Compiler.Steps.InjectCallableConversions}
+		[45]	{Boo.Lang.Compiler.Steps.ImplementICallableOnCallableDefinitions}	object {Boo.Lang.Compiler.Steps.ImplementICallableOnCallableDefinitions}
+		[46]	{Boo.Lang.Compiler.Steps.CheckNeverUsedMembers}	object {Boo.Lang.Compiler.Steps.CheckNeverUsedMembers}
+		[47]	{Boo.Lang.Compiler.Steps.EmitAssembly}	object {Boo.Lang.Compiler.Steps.EmitAssembly}
+		[48]	{Boo.Lang.Compiler.Steps.SaveAssembly}	object {Boo.Lang.Compiler.Steps.SaveAssembly}
 
 
第 0 步由 Boo.Lang.Compiler.Pipelines.Parse (src\Boo.Lang.Compiler\Pipelines\Parse.cs) 加入。 
第 1～27 步由 Boo.Lang.Compiler.Pipelines.ResolveExpressions (src\Boo.Lang.Compiler\Pipelines\ResolveExpressions.cs) 加入。 
第 28～46 步由 Boo.Lang.Compiler.Pipelines.Compile (src\Boo.Lang.Compiler\Pipelines\Compile.cs)加入。 
第 47 步由 Boo.Lang.Compiler.Pipelines.CompileToMemory (src\Boo.Lang.Compiler\Pipelines\CompileToMemory.cs) 加入。 
第 48 步由 Boo.Lang.Compiler.Pipelines.CompileToFile (src\Boo.Lang.Compiler\Pipelines\CompileToFile.cs)加入。 
 
這些步驟都是利用繼承的關係建立起來的：CompileToFile -&amp;gt; CompileToMemory -&amp;gt; Compile -&amp;gt; ResolveExpressions -&amp;gt; Parse 
只應用了繼承的威力... 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6049291.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 19 May 2008 14:30:22 +0800</pubDate>
					</item>
	<item>
		<title>Boo(12)-函數 / Thinking more...</title>
		<description>函數定義方法很簡單，比較特別的就是不定個數變數。 
 
// Say
def Say( s as string):
	print s

// 也是 Say
def Say( i as int):
	print i

// 不定個數
def Say(*args as (object)):
	print &quot;len(args)=${len(args)}&quot;
	for arg in args:
		print arg

// 求平方
def pow( i as int ) as int:
	return i*i

Say( &quot;Hello world!&quot; )
Say( 20 )
Say( pow( 2 ) )
Say( 1, &quot;s&quot;, join(range(10)) )

a = (5, 8, 1, &quot;end&quot;)
Say(*a)
 
as string、as int...等，其實都可以省略不寫，別忘了 Boo 會自動判定。 
然後有看到 Say() 定義了三次嗎？是的，Boo 支援多載(overloading)。 
不定個數變數，定義的方法比較特別，要加上 *，然後用法就當作是 enumerator 來用就行了。 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6033657.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 16 May 2008 16:55:38 +0800</pubDate>
					</item>
	<item>
		<title>ILMerge / Thinking more...</title>
		<description>這工具可以讓你把 .Net 不同語言編譯出來的 Assembly (組件)合併在一起。

官方網址： ILMerge 

安裝以後，用法很簡單：
 &quot;c:\Program Files\Microsoft\ILMerge\ILMerge.exe&quot; /t:library /out:[輸出檔名] /lib:[Assembly搜索路徑] [要合併的 Assembly 1] [要合併的 Assembly 2] ... 

只想給客戶一個可執行檔，不想給一堆其他組件的時候，這樣作也行：
 &quot;c:\Program Files\Microsoft\ILMerge\ILMerge.exe&quot; /t:[exe或winexe] /out:[輸出檔名] /lib:[Assembly搜索路徑] [執行檔] [要合併的 Assembly 1] [要合併的 Assembly 2] ... 

對，合併以後，檔案絕對變大，然後千萬不要忘記了，要測試。另外，ILMerge 文件(ILMerge.doc)裡面有些限制以及問題，甚至是用法都有詳細描述，要記得閱讀...
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6027919.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 15 May 2008 15:16:32 +0800</pubDate>
					</item>
	<item>
		<title>switch-case in boo / Thinking more...</title>
		<description> Boo 本身並沒有類似 switch-case 語法，但是可以藉著 macro 來做到， Boo extensions 這個專案已經寫好了。 
由於這個專案沒有釋出二進位碼，所以你需要自己 checkout 並編譯。 
 
編譯以後，用法也很簡單，一看就能懂了。
 
import Boo.PatternMatching  // match 與 case 這兩個 macro 都在這裡面

def getEnglish( i as int ) as string:
	s = &quot;&quot;
	match i:
		case 0:
			s = &quot;zero&quot;
		case 1:
			s = &quot;one&quot;
		case 2:
			s = &quot;two&quot;
		case 3:
			s = &quot;three&quot;
		otherwise:
			s = &quot;unknown&quot;
	return s

l = array( typeof(int), range( 5 ) )
for item in l:
	print getEnglish( item )
 

未來  Boo extensions  會包進  Boo  嗎？很難說... Boo extensions  目前仍然很具實驗性... 
 
P.S.   編譯 Boo extensions 前，請下載最新的  Boo ，然後解壓縮以後，放到跟 boo-extensions 同一層。再切換到 boo-extensions/extensions 下執行  nant  即可。  如果  Boo extensions  無法編譯成功，試著修改 extensions/default.build 將編譯 .Test.dll 的幾個地方註解掉，再次編譯即可。這些 .Test.dll 其實是用不到的。  
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6023571.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 14 May 2008 16:20:17 +0800</pubDate>
					</item>
	<item>
		<title>Boo(11)-Hash / Thinking more...</title>
		<description>Hash 的用法很簡單，同樣地，跟 array、List 一樣，可以用很簡潔的方式來表示，也就是大括號 { } 
或者，也可以將符合 key、value 格式的有 IEnumerable 介面的變數傳入 Hash() 函數來取得。 
 
 
h1 = { &#039;a&#039;: 65, &#039;b&#039;: 66, &#039;c&#039;: 67 }
print h1[&#039;a&#039;]
h2 = Hash( ( (&#039;a&#039;,65), (&#039;b&#039;,66), (&#039;c&#039;,67) ) )
h3 = Hash( [ (&#039;a&#039;,65), (&#039;b&#039;,66), (&#039;c&#039;,67) ] )
 
 
沒有 Generic 版本的 Hash 可以參考 src/boo.lang/Hash.cs，它其實是繼承自 Hashtable﹔有 Generic 版本的，就直接參考 System.Collections.Generic 裡面的 Hash 吧～
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/6014469.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 12 May 2008 16:34:12 +0800</pubDate>
					</item>
	<item>
		<title>Boo(10)-Array / Thinking more...</title>
		<description>陣列的定義方法主要有兩種：  使用小括號 (,) 來定義。  使用函數： array()、matrix() 來取得。  
要得到陣列的大小，則可以使用 len (參考原始碼 tests/testcases/integration/primitives/len-1.boo)，直接來看範例吧：
 
a0 = (,) // 空的陣列
a1 = ( 1, 2, 3, 4, 5 )  // 都是整數的陣列
a2 = array( range(5) )  // 同樣也是得到整數陣列
a3 = matrix( typeof(int), 2, 3 ) // 得到一個 2x3 的陣列，也可以多傳幾個，製造一個瘋狂的多維陣列
a4 = array( typeof(int), 5 )  // 也是得到一個整數陣列
a3[0,0] = 1
a3[1,0] = 2
print &quot;len(a3,0)=&quot; + len(a3,0)  // 得到 a3 第一維的大小
print &quot;len(a3,1)=&quot; + len(a3,1)  // 得到 a3 第二維的大小
for i in a3:
  print i
a4 = ( 1, &#039;a&#039;, 2, &#039;b&#039; )  // 雖然陣列要求都是相同型別，但是這樣寫也可以，只是得到型別都是 object 的陣列
// 輸出結果
// 1
// 0
// 0
// 2
// 0
// 0
// len(a3,0)=2
// len(a3,1)=3
 

陣列也可以用 Generic 語法(參考原始碼 tests/testcases/parser/array_list_hash_literals.boo)，只是我覺得並不是像 List 那麼的必要就是了～：
 
 a5=(of int: 1,2,3)
 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/5994715.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 08 May 2008 15:20:22 +0800</pubDate>
					</item>
	<item>
		<title>偵測 .Net/Mono 安裝目錄與 CLR 版本 / Thinking more...</title>
		<description>參考自： How to determine the .NET installation directory and CLR version 
 
env=System.Runtime.InteropServices.RuntimeEnvironment()
print env.GetRuntimeDirectory()
print env.GetSystemVersion()
print env.SystemConfigurationFile
// 輸出結果 (Ubuntu 8.04 + Mono 1.2.6)
// /usr/lib/mono/2.0
// v2.0.50727
// /etc/mono/2.0/machine.config
 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/5994219.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 08 May 2008 13:21:31 +0800</pubDate>
					</item>
	<item>
		<title>Boo(9)-List / Thinking more...</title>
		<description> Boo 的 List 並不是使用 .Net/Mono 的 List，而是自己實作。 
使用的方法很簡單，用中括號或是使用List函數。 
 
l1=[ 1, 2, 3, 4, &quot;a&quot;, &quot;b&quot;, &quot;c&quot; ]
l2=List( range(10) )
l1.Add( &quot;d&quot; )
l2.Add( &quot;d&quot; )
print l1
print l2
l1.Remove( &quot;d&quot; )
// 輸出結果
// [1, 2, 3, 4, &quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;]
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, &quot;d&quot;]
// [1, 2, 3, 4, &quot;a&quot;, &quot;b&quot;, &quot;c&quot;]
 

除了正常 List 的操作 Add()、Remove() 以外，還提供了 Push()、Pop()，這意味著可以把 List 當 Stack 來使用。 
 
如果你想知道更多 List 的操作，可以在 booish 裡面使用 dir()，來查看。
 
&amp;gt;&amp;gt;&amp;gt;l=[]
&amp;gt;&amp;gt;&amp;gt;dir(l)
 
 
由於 dir() 會傳回一個 IEnumerator，所以你也可以用下面的程式把每個項目輸出。
 
l=[]
for m in dir(l):
	print m
 
 
或者，直接參考  Boo  的原始碼 src/boo.lang/list.cs 。 
 
隨著 .Net framework 2.0 推出，Boo 也支援了 Generic 語法，語法可以參考這篇的說明： Boo Generic Syntax 
 
import System.Collections.Generic

l = List[of int]()
l.Add( 10 )
l.Add( 20 )
for i in l:
  print i
l.Add( &quot;hello&quot; )  // 這行將會發生錯誤，告訴你不可以加入字串型別
 
 
首要的一件事，就是先 import System.Collections.Generic，表明要使用 Generic，否則之後的程式會無法執行。接著使用 [of Type] 的語法，表示 List 要使用指定 Type 的泛型。 
 
使用泛型最明顯的好處是省去轉型的麻煩，因為 List 裡面預設都是使用 object 型別，改用 Generic 以後，可以預先指定好 List 裡面的元素要使用什麼型別。 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/5983853.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 06 May 2008 16:51:50 +0800</pubDate>
					</item>
	<item>
		<title>求1到50之間所有偶數的平方值總和 / Thinking more...</title>
		<description>剛好看到： 求1到50之間所有偶數的平方值總和 ，於是順手寫一寫：
 
//
// Sum all even in 1~50
//
import System

sum = 0
for i in range(1,51):
 if i%2==0:
  sum+=i*i
print sum
 </description>
		<link>http://blog.roodo.com/thinkingmore/archives/5966103.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 02 May 2008 23:07:57 +0800</pubDate>
					</item>
	<item>
		<title>Boo(8)-迴圈 / Thinking more...</title>
		<description>基本上迴圈有兩種：for 與 while。 

for 與一般語言的 for 不太一樣，反而與 foreach 比較類似，為了要能得到一個 Enumerator，通常都搭配 range()：
 
// 印出 0 到 4
for i in range(5):
  print i
 

while 也沒什麼特別的：
 
// 同樣印出 0 到 4
i=0
while i 

 Boo Primer 還有提出所謂的 do-while，但實際上是運用 while + break + unless修飾詞來達成的：
 
// 也是印出 0 到 4
i=0
while true:
  print i
  i=i+1
  break unless i 

有 break，當然也有 continue：
 
// 印出 1 3 5 7 9
for i in range(10):
  continue if i%2==0
  print i
 

另外再提一個關鍵字，就是 pass，這用來表示程式區塊內不做事情：
 
// 不會輸出任何結果，因為被 pass 掉了...
i=2
if i%2==0:
  pass
else:
  print &quot;i!=2&quot;
 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/5955257.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 30 Apr 2008 16:34:09 +0800</pubDate>
					</item>
	<item>
		<title>Boo and Split / Thinking more...</title>
		<description>剛好遇到這種狀況，要依據字串的某字元然後做出陣列。所以很直覺地，就可以寫出這樣的代碼。
 
    splitter = ( char(&#039;,&#039;), char(&#039;\n&#039;) )
    fields = inputText.Split( splitter )
 

不過這段代碼足以讓人搞半天了，boo 會不讓你執行。 
非常感謝 Google 網上論壇 的Boo Programming Language群組 ：   Split    how do I use Split?   
正好解答了我的問題，原來要這樣寫：
 
    splitter = ( char(&#039;,&#039;), char(&#039;\n&#039;) )
    fields = inputText.Split( *splitter )
 
 
這真是太隱晦不明了...
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/5952383.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 30 Apr 2008 01:13:21 +0800</pubDate>
					</item>
	<item>
		<title>Boo(7) - if-elif-else、unless / Thinking more...</title>
		<description>Boo 的 if 述句與 python 相似：
 
i=5
if i&gt;5:
	print &quot;i大於5&quot;
elif i==5:
	print &quot;i等於5&quot;
else:
	print &quot;i小於5&quot;
 
 
很簡單。這邊額外要提到程式區塊的概念，像 C# 是用 { }，Pascal 用 begin end，Python 與 Boo 是用縮排來決定程式區塊，所以縮排使用的字元很重要，千萬不要混雜使用，否則你會錯的莫名其妙，在開發時，最好一開始就決定好要使用 tab 字元或是特定數目的空白字元。 
 
運算式，可以使用 and, or 來作連接，或是使用 not 來表示需要相反的條件式。
 
i=7
if i&gt;=5 and i 
 
如果你沒接觸過 perl/python/ruby/php 的話，以下的用法應該會讓你感到新奇：
 
s=&quot;sad&quot;
unless s==&quot;sad&quot;:
	print &quot;Hello world!&quot;
print &quot;Hello world!&quot; unless s==&quot;sad&quot;
print &quot;I am sad&quot; if s==&quot;sad&quot;
 
 
unless 是反面的 if，把它想成 if not 就對了，所以第三行並不會被執行。 
此外，unless 與 if 也可以用來修飾前面的述句﹔以第四行來說，unless s==&quot;sad&quot;用來修飾前面的 print &quot;Hello world!&quot;﹔以第五行來說，if s==&quot;sad&quot;用來修飾前面的print &quot;I am sad&quot;﹔當條件符合時，才會印出。 
因此第四行的 &quot;Hello world!&quot; 不會被印出，而第五行的 &quot;I am sad&quot; 則會被印出。 
 
這些用法會讓人覺得程式也很口語化～ 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/5935747.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 28 Apr 2008 17:46:12 +0800</pubDate>
					</item>
	<item>
		<title>Boo(6)-變數 / Thinking more...</title>
		<description> Boo  的變數宣告方法很簡單，就跟大多數的 script 語言一樣，指定即用。 
比較特別的地方有三個：  在第一次指定以後，該變數型別就確定了，之後若指定其他型別的值給它，會發生錯誤。這邊的行為跟 Python、Ruby、Javascript等 script 語言不同，要特別注意。這也證明了 Boo 具有靜態語言的特性。  字串裡可以用 ${var_name} 的方式，會直接把 var_name 的值放到變數裡面去。  字串有三種定義方法：  雙引號，如&quot;Hello&quot;  單引號：跟雙引號的不同處，在於單引號字串不解釋 ${}，所以 print &#039;${var}&#039; 會印出 ${var}，而不是 var 變數的值。  三個雙引號，如 &quot;&quot;&quot;Hello&quot;&quot;&quot;，跟前兩者的差別在於可以跨越多行。這跟 python 一樣。   

 // var.boo
i = 100
s = &quot;Hello world ${i} times!!&quot;
print s

// 如果把 100 指派給 s，就會發生錯誤
// s = 100
// Boo Primer 說可以像下面這樣寫，但經過我試驗，是不行的。
// s as int = 200
// 但這樣寫，卻是可以的
o as object = 300
print o
o = &quot;I am object&quot;
print o

print &quot;&quot;&quot;Hello
Line1
Line2
Line3&quot;&quot;&quot;
 

 Boo  官方建議不要特別花心思去寫 &amp;lt;variable&amp;gt; as &amp;lt;type&amp;gt; = &amp;lt;value&amp;gt; 這樣的語法，盡量使用 &amp;lt;variable&amp;gt; = &amp;lt;value&amp;gt;。 
經過編譯(booc -target:exe var.boo)以後，再用 reflector 去反組譯，產出的C#代碼如下： private static void Main(string[] argv)
{
    int num = 100;
    Console.WriteLine(new StringBuilder(&quot;Hello world &quot;).Append(num).Append(&quot; times!!&quot;).ToString());
    object obj2 = 300;
    Console.WriteLine(obj2);
    obj2 = &quot;I am object&quot;;
    Console.WriteLine(obj2);
    Console.WriteLine(&quot;Hello\r\nLine1\r\nLine2\r\nLine3&quot;);
}
 
 
從反組譯出來的結果看來， Boo 都幫你自動處理好了，的確是不用特別花心思去寫。 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/5911025.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 23 Apr 2008 17:33:10 +0800</pubDate>
					</item>
	<item>
		<title>Boo(5) - Console.ReadKey() / Thinking more...</title>
		<description>承接上篇的討論，經過 Hack 之後，發現原因就出在 Console.ReadKey()。 
 
booish 與  IronPython  為了要能達到自己的需求，所以並不使用 Console.ReadLine()，而是使用 Console.ReadKey() 自行處理收到的按鍵並輸出。 
為了要知道為甚麼會有問題，我試著寫了一個小程式，想知道相似的方式，是否也會有同樣的問題發生：
 // Program: readkey.cs
// How to compile: gmcs /target:exe readkey.cs
using System;
public class Hello {
	public static void Main( string[] args ) {
		Console.TreatControlCAsInput = true;
		ConsoleKeyInfo keyInfo;
		do
		{
			keyInfo = Console.ReadKey( true );
			Console.Write( keyInfo.KeyChar );
		} while( keyInfo.Key!=ConsoleKey.Escape );
	}
}
 

這個小程式編譯以後，使用 .NET 來執行，一切正常，但使用 Mono  Windows 版來執行，就硬是會 echo 出兩次。 
經過用 Reflector 比對以後，發現 Mono 的 Console.ReadKey() 的迴圈條件式有問題。 
如果將該條件式修正為：
 
	// } while( record.EventType != 1 &amp;&amp; !record.KeyDown); // original
	} while( !(record.EventType==1 &amp;&amp; record.KeyDown ) );

	// 附帶一提，這是 Windows .NET 的版本的變形，多判斷了 Character==&#039;\0&#039; 與 VirtualKeyCode 不是 Ctrl、alt、shift、numlock、caplock、scrolllock 的情況
	//} while( !(record.EventType==1 &amp;&amp; record.KeyDown ) || record.Character==&#039;\0&#039; &amp;&amp; ( ((record.VirtualKeyCode 0x12) &amp;&amp; record.VirtualKeyCode!=0x14 &amp;&amp; record.VirtualKeyCode!=0x90 ) ? (record.VirtualKeyCode==0x91) : true ) );
 
就可以解決問題，我想這可能是因為寫作 WindowsConsoleDriver.cs 的人對 ReadConsoleInput() 不夠清楚的緣故，不過其實我也是看了 source code 才知道要這樣去判斷。 
總之，一切就此水落石出。 
 
等等，可是為甚麼 Console.ReadLine() 沒有問題呢？嗯嗯，這邊的原因也很簡單，因為不管是 .NET 的 CLR 或是  Mono ，都是調用 stdin 進行處理，所以就沒有這樣的問題了。 
 
解決方法，目前並沒有，應急的方法是自行下載原始碼，修正Console.ReadKey()(在class/corlib/System/WindowsConsoleDriver.cs)以後，再編譯。不急的話，是先上 Mono Buzilla 去找找看是否有人回報過此問題，如果沒有再回報上去。 
晚點要去找找看，然後回報上去，希望下個版本能解決。 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/5895705.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 21 Apr 2008 14:34:32 +0800</pubDate>
					</item>
	<item>
		<title>Boo(4) - booi 與 booish / Thinking more...</title>
		<description>Boo 有兩個很方便的工具：booi 與 booish

booi 可以用來直接執行你寫好的 script，而不必事先編譯。
而 booish 則可以讓你直接輸入指令，立即就能看到結果。

類比其他語言的話，booi 用法就像是執行 wscript your_script 或是 python your_script：booi your_script。
booish 就像是單獨執行  Python  或  ruby  是一樣的，執行以後，會出現訊息以及提示符號。
booish 的提示符號是 &amp;gt;&amp;gt;&amp;gt; ，與  Python  一樣，使用方法也很類似。

使用 booish 的時候，我發現很詭異的地方，就是使用  Mono  包進來的 booish 與 ipy (IronPython) 時，輸入任何字元，都會自動出現兩次以上...
 boo 官方網站 所提供的 booish 就沒有這個問題，這讓我很納悶。
有時間來找找這問題發生的原因。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/5881295.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 18 Apr 2008 17:25:11 +0800</pubDate>
					</item>
	<item>
		<title>Boo(3) - ildasm / Thinking more...</title>
		<description>使用 ildasm 有兩個目的：  比較print macro 與 print 函數的差別  比較 booc 編譯出來的可執行檔與 c# 編譯出來的可執行代碼  

print macro 與 print 函數算是差別很大吧。
print 函數會調用 Boo.Lang.Builtins 類別裡的 print 函數，雖然實際上此函數的內容也是使用 Console.WriteLine()，但是除了你需要多附上 Boo.Lang.dll 之外，你還需要負擔 CLR 執行時動態把 Boo.Lang.dll 載入的成本。
 IL_0005:  call       void [Boo.Lang/*23000001*/]Boo.Lang.Builtins/*01000001*/::print(object) /* 0A000001 */ 
使用 print macro 的話，就只是把 Console.WriteLine 替換進去，以編譯出來的結果而言，這會比較有效率，但如果作為 script 執行時，我想應該會有些損失。
 IL_0005:  call       void [mscorlib/*23000001*/]System.Console/*01000001*/::WriteLine(string) /* 0A000001 */ 
這就是為甚麼 BOO Primer 建議使用 print macro 的原因。

booc 編譯出來的結果與使用 gmcs (我使用  Mono  的 c# 2.0 編譯器)編譯出來的結果非常接近，都同樣直接呼叫 System.Console.WriteLine，可以視為一樣。
p.s. 我也看過以 csc 編譯出來的結果了，實際上也非常相近，不過反組譯出來的IL代碼裡面的編排有些許不同。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/5869723.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 16 Apr 2008 14:40:54 +0800</pubDate>
					</item>
	<item>
		<title>BOO(2) - Hello world! / Thinking more...</title>
		<description>接下來的系列文章，大致會照著 BOO Primer 的章節來作介紹。 
 
是的，永遠的 Hello world! 
 
BOO 的 Hello world! 非常簡單： // 把 print 當 macro 使用，什麼是 macro ??日後再說明
print &quot;Hello world!&quot;
// 或者是拿 print 當函數使用
print(&quot;Hello world!&quot;)
 
 
官方建議使用 print macro 的版本，我想是效率上的考量，macro 在執行時會展開為真正的代碼，而不是以函數呼叫的方式來處理。不過我覺得這見仁見智，差別不是很大。另一個好處應該是很像  Python  吧～ 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/5859319.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 14 Apr 2008 15:16:49 +0800</pubDate>
					</item>
	<item>
		<title>BOO (1) / Thinking more...</title>
		<description> BOO 是一個兼具動態語言特性與靜態語言特性的語言，比 IronPython 、 IronRuby 還要早誕生，但是使用的人卻不多，我對他會有興趣的原因是因為他很接近 Python，而且可以編譯為 exe/dll、定義出屬於自己的  Domain-specific language (使用 macro)。

Q:哪裡可以取得？
A:你可以到  BOO 官方下載網頁  下載。

Q:如何安裝？
A:解開下載來的壓縮檔即可，除此之外，你還需要安裝  .Net framework 2 ，這可以用 Windows Update 裝起來。此外，你也可以透過安裝 Mono 或是 SharpDevelop 2.x 的方式來取得。

Q:跟其他 .Net 語言，如 c#, vb.net 等，有什麼不一樣？
A:最大的不同點在於 BOO 可以當作 script 來使用，你可以使用 booi 直接執行程式，或是像 Python 一樣，當作 SHELL 來使用 (booish)。

Q:如何使用？
A:  當作 shell 來使用：解開之後，你可以在 bin 目錄下找到 booish.exe，點選以後執行。  執行 script：在命令提示字元下切換目錄到 boo_path/bin 以後，輸入 booi your_script.boo  編譯為 dll/exe：在命令提示字元下切換目錄到 boo_path/bin 以後，輸入 booc -target:[exe|library|winexe] -o:輸入檔名 your_script.boo  

Q:有哪些文件可以參考？
A:官方網站的  Tutorials  列出了相當多的文件，我自己主要是參考 Boo Primer 。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/5843991.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 11 Apr 2008 13:18:42 +0800</pubDate>
					</item>
	<item>
		<title>包在 Mono Windows 版裡的東西 / Thinking more...</title>
		<description>再隨手記下一些：
  VisualPng.exe，可以看 png 的軟體  webshot.bat，可以抓取網頁當作圖片的 console 程式，不過在 Windows 跑不起來，會丟出需要 gtkembedmoz 的錯誤訊息  ipy、ipy2，是的，有把 IronPython 包進來，不過互動模式怪怪的。  ikvm，這是之前就有的，詳情請參考 ikvm 官方網頁說明，是可以讓 Java 程式在 mono 上執行的程式(甚至是互轉)  jay，類似 yacc 的 parser，是的，c# compiler 就是以此為基礎  xulrunner，好像是這一版才加入的，印象中之前並沒有，用途不明...  cilc，用途不明，help 是寫：Mono CIL-to-C binding generator  monop、monop2，把類別的公開介面列出來的 console 程式  monolinker，可以只把需要的類別抽取出來或是把一些程式安插進去的程式。  
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/5831551.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 08 Apr 2008 16:49:33 +0800</pubDate>
					</item>
	<item>
		<title>pythonw 與 monow / Thinking more...</title>
		<description>Windows 版的  Python  在安裝以後，你會發現目錄下除了 python.exe 以外，還有一個 pythonw.exe，這是做什麼的呢？
簡單的說，python.exe 是一個 console 程式，執行  Python  程式的時候，在建立捷徑的時候，你會這樣寫：python your_app.py，但是執行時會出現一個黑色的 console 視窗。
pythonw.exe 作用則在於，不出現那個黑色的 console 視窗。

好，那 monow 的作用為何，你應該也能了解了吧～

特別指出這個的原因，是因為我這幾天在看  Mono  裝了什麼東西時發現的，其實我陸續還有看到一些東西，慢慢再介紹。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/5824561.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 07 Apr 2008 14:10:52 +0800</pubDate>
					</item>
	<item>
		<title>亂碼 1/2 / Thinking more...</title>
		<description>此亂碼非彼 亂馬 啊～
家裏 Server 的  Mono  升級到 1.9 以後，ASP.Net 網頁裡的中文突然都變成了亂碼，可是我什麼都沒改啊～
由於個人因素 (就是懶啦)，一直都沒去管，今天看開了，決定找出真兇...

首先試著直接跑 xsp2 之後，用 Browser 去看結果，正常，沒有亂碼。很好，那麼應該是 mod_mono 跟 Apache 的問題囉～
再看看有亂碼的網頁，看看送出來的網頁與 Response header 是否正確，送出來網頁的中文都變成了 ?，可是從資料庫撈出來的字卻又都沒問題，可以正常顯示，網頁的 Response header 也沒問題。很好，那真的是 mod_mono 與 Apache 的問題了。

仔細看了 mod_mono 的設定，唯一我覺得有問題的，就是 MonoSetEnv，可是我確實地已經設定了 MonoSetEnv &quot;LANG=en_US.UTF-8&quot;，應該不會有問題才對。
好，那麼就寫個簡單的網頁把所有環境變數列出來看看，果不其然，LANG = C，這表示LANG並沒有被設定，那麼會出現亂碼也是很正常的了。LANG 對 Linux 來說，是很重要的環境變數，沒有這個，很多應用程式將無法判斷目前所在的語系與編碼。
那麼是 mod_mono 問題囉？可是看過  source code  之後，發現沒有特別針對 MonoSetEnv 做什麼修正，再回頭看看列出來的環境變數，我發現我在設定檔裡面設定的 TEMP 環境變數有生效，那麼?!

再仔細看一次 mod_mono 的說明，原來如果你要設定多個環境變數時，要加上 &#039;;&#039;，所以在我改寫為 MonoSetEnv &quot;LANG=en_US.UTF-8;TEMP=/var/tmp&quot;，重新啟動之後，問題就解決了。

p.s. 那...為啥以前沒錯?! 我想可能是  Apache  的 apr 行為有改變吧～
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/5797269.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 02 Apr 2008 17:05:17 +0800</pubDate>
					</item>
	<item>
		<title>Banshee hack / Thinking more...</title>
		<description>從 src/Core/Banshee/Services/Banshee.Database/BansheeDbFormatMigrator.cs 的InitializeFreshDatabase()裡面可以看到 Banshee 建立了這些 table：  CoreConfiguration  CoreTracks  CoreArtists  CoreAlbums  CorePlaylists  CorePlaylistEntries  CoreSmartPlaylists  CoreSmartPlaylistEntries  CoreRemovedTracks  CoreTracksCache  CoreCache  
並且針對各個 Table 建立了必要的 Index (好吧，我的疑慮解除了，其實  Banshee  有幫建檔的音樂作索引，那還要繼續看下去嗎?)

BansheeDbFormatMigrator.cs 裡面還可以看到以 Migrate_ 開頭的函式前面有 [DatabaseVersion] 這個 Attribute，這些函式是用來作 Migrate(升級)的函式，Banshee 會先檢查 CoreConfiguration table 的 DatabaseVersion 欄位，看目前 Database 是什麼版本，然後再決定要怎麼去作升級(這部份可以參考 Migrate(), InnerMigrate())。

存取資料庫的部份被包在 src/Core/Banshee.Services/Banshee.Collection.Database下的各個以 AlbumInfo 結尾的檔案裡面，裡面都大同小異，provider 成員為主要的提供者，這裡會傳入 ServiceManager.DbConnection 讓 BansheeModelProvider 的 instance 能根據此 connection 去存取資料庫。
所有的 connection 都是由 ServiceManager.DbConnection (src/Core/Banshee.Services/Banshee.ServiceStack/ServiceManager.cs) 而來，而 DbConnection 其實只是一個服務 (src/Core/Banshee.Services/Banshee.Database/BansheeDbConnection.cs)，在 ServiceManager 被初始化(static ServiceManager())的時候被註冊進去。

BansheeDbConnection 繼承自 HyenaSqliteConnection (src/Libraries/Hyena/Hyena.Data.Sqlite/HyenaSqliteConnection.cs)，從 HyenaSqliteConnection.cs 看起來似乎是為了要把存取資料庫這整個部份獨立為 Thread 以提昇 UI 效率，所以才另外作 Hyena.Data.Sqlite。
不過最終底層還是  Sqlite 3 。

 Banshee  的 Main() 在 Client 類別 (src/Client/Nereid/Nereid/Client.cs)，Client 繼承自 GtkBaseClient (src/Core/Banshee.ThickClient/Banshee.Gui/GtkBaseClient.cs)，扣掉註解不到 30 行...

補充1： HACKING Guide 
補充2：我看的 code 是目前最新的版本，後來看過 0.13 的資料庫，發現的確沒有建 Index。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/5732279.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 21 Mar 2008 10:36:50 +0800</pubDate>
					</item>
	<item>
		<title>c# Iterator / Thinking more...</title>
		<description>這裡沒有要解說什麼，下面這段程式是從 c# specification 來的，而程式本來是不能執行的，是的，範例有問題。問題點：  原本的 IEnumerator&amp;lt;T&amp;gt; GetEnumerator() 應該加上 IEnumerable&amp;lt;T&amp;gt;.，成為 IEnumerator&amp;lt;T&amp;gt; IEnumerable&amp;lt;T&amp;gt;.GetEnumerator()   少繼承了 IEnumerable 介面並實做 IEnumerable.GetEnumerator()   
我查了很久，才找到問題點，另外還參考  Bertrand Le Roy  的文章，精簡了 IEnumerable.GetEnumerator() 的代碼。 
 
Iterator 就類似 Python/Boo Generator 的概念，目前我認知到最大的好處是，不一定要讓迴圈全部跑完，就可以先傳回一個值去處理。 
 
 using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;

public class Tree&amp;lt;T&amp;gt;: IEnumerable&amp;lt;T&amp;gt;, IEnumerable
{
	T value;
	Tree&amp;lt;T&amp;gt; left;
	Tree&amp;lt;T&amp;gt; right;
	public Tree(T value, Tree&amp;lt;T&amp;gt; left, Tree&amp;lt;T&amp;gt; right) {
		this.value = value;
		this.left = left;
		this.right = right;
	}
	
	IEnumerator&amp;lt;T&amp;gt; IEnumerable&amp;lt;T&amp;gt;.GetEnumerator() {
		if (left != null) {
			foreach (T x in left) 
				yield return x;
		}
		yield return value;
		if (right != null) {
			foreach (T x in right) 
				yield return x;
		}
	}

	// Yield and generics rock! - Tales from the Evil Empire &amp;lt;http://weblogs.asp.net/bleroy/archive/2004/08/31/223531.aspx&amp;gt;
	IEnumerator IEnumerable.GetEnumerator() {
		return (IEnumerator)(((IEnumerable&amp;lt;T&gt;)this).GetEnumerator());
	}
}

public class Program
{
	static Tree&amp;lt;T&amp;gt; MakeTree&amp;lt;T&amp;gt;(T[] items, int left, int right) {
		if (left &amp;gt; right) 
			return null;
		int i = (left + right) / 2;
		return new Tree&amp;lt;T&amp;gt;(items[i], 
			MakeTree(items, left, i - 1),
			MakeTree(items, i + 1, right));
	}
	static Tree&amp;lt;T&amp;gt; MakeTree&amp;lt;T&amp;gt;(params T[] items) {
		return MakeTree(items, 0, items.Length - 1);
	}
	// The output of the program is:
	// 1 2 3 4 5 6 7 8 9
	// Mon Tue Wed Thu Fri Sat Sun
	public static void Main() {
		Tree&amp;lt;int&amp;gt; ints = MakeTree(1, 2, 3, 4, 5, 6, 7, 8, 9);
		foreach (int i in ints) 
			Console.Write(&quot;{0} &quot;, i);
		Console.WriteLine();
		Tree&amp;lt;string&amp;gt; strings = MakeTree(
			&quot;Mon&quot;, &quot;Tue&quot;, &quot;Wed&quot;, &quot;Thu&quot;, &quot;Fri&quot;, &quot;Sat&quot;, &quot;Sun&quot;);
		foreach (string s in strings) 
			Console.Write(&quot;{0} &quot;, s);
		Console.WriteLine();
		Console.ReadLine();
	}
}
 

額外的收穫是，發現 mono gmcs 編譯出來的代碼比 Microsoft csc 編譯出來的代碼要多出約四百多個 bytes。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/5574113.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 21 Feb 2008 18:12:01 +0800</pubDate>
					</item>
	<item>
		<title>ASP.Net in Debian/Ubuntu / Thinking more...</title>
		<description>在  Ubuntu  下架設 mono xsp 其實還蠻愉快的。 
 Debian / Ubuntu 的mono-xsp2套件提供了 mono-xsp2-admin 指令，用這個很快就能新增/刪除你的應用程式。 
用法很簡單： sudo mono-xsp2-admin add --path=your_app_path --application=/your_app_name 
接著重新啟動 mono-xsp2 服務即可： sudo /etc/init.d/mono-xsp2 restart 
這個方法不需要安裝 mod_mono，因為這個時候 xsp2 是以一個獨立的 Daemon 存在。如果你希望 xsp2 應用程式是作為  Apache  Web server 下的一個子目錄的話，你需要安裝 mod_proxy, mod_proxy_http, mod_proxy_html： sudo apt-get install libapache2-proxy-html
sudo a2enmod proxy proxy_html 

然後在你的 VirtualHost 設定裡面加上：     &amp;lt;Proxy *&amp;gt;
        Order deny,allow
        Allow from all
    &amp;lt;/Proxy&amp;gt;

    ProxyPass /your_app_name http://localhost:your_port/your_app_name
    ProxyPassReverse /your_app_name http://localhost:your_port/your_app_name

    ProxyHTMLURLMap http://localhost:your_port /your_app_name/

    &amp;lt;Location /your_app_name&amp;gt;
        ProxyPassReverse /
        SetOutputFilter proxy-html
        ProxyHTMLURLMap / /your_app_name/
        Order allow,deny
        Allow from all
    &amp;lt;/Location&amp;gt;
 
 
接著重新啟動 Apache，這時候你在瀏覽器的網址列輸入 http://localhost/your_app_name/ 應該就可以存取到你的 asp.net 應用程式了。 
 
備註：如果你不想使用 mono-xsp2，而只想把 Apache 當作前端，IIS當後端的話，同樣也可以用 mod_proxy, mod_proxy_html, mod_proxy_http 來解。 
 
參考資料：   Using Apache with mod_proxy - Confluence 2.7 - Confluence    Running a Reverse Proxy with Apache:    mod_proxy_html   
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/5500251.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 04 Feb 2008 17:04:52 +0800</pubDate>
					</item>
	<item>
		<title>String.IsNullOrEmpty / Thinking more...</title>
		<description> 長見識 ，原來 .Net framework 2 之後為 String 多提供了一個方便的 Method： IsNullOrEmpty  
 
所以以後可以不用寫成這樣了： 
string s;
if( s!=null &amp;&amp; s!=String.Empty )
{
  // do something
}
 
 
補充：不過有文章( DANGER ! String.IsNullOrEmpty can lead to runtime Null exceptions !! - @ Head )指出這方法其實有可能會丟出 Null exception.
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/5133623.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 25 Jan 2008 09:45:20 +0800</pubDate>
					</item>
	<item>
		<title>為 Mono c# 編譯器的輸出添加一點色彩 / Thinking more...</title>
		<description> Miguel 大 日前為 Mono c# 編譯器加了一點小小的加強( Colorful Error Output )，只要設定MCS_COLOR環境變數，就可以讓編譯器的輸出有比較顯目的色彩：
 export MCS_COLORS=errors=brightwhite,red 

如果你要關閉這功能的話，只要用
 export MCS_COLORS=disable 
就可以關閉。

不過照 文章 的日期看來，這功能應該在 1.2.7 以後才會有～
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/4963207.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 11 Jan 2008 18:10:11 +0800</pubDate>
					</item>
	<item>
		<title>在 Monorail 裡啟動 Logging 的方法 / Thinking more...</title>
		<description>參考這篇： Enabling logging 就行了。 
 
整理如下：
  在 public 下新增一個檔案 log4net.config： 
&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&amp;gt;
&amp;lt;configuration&amp;gt;
    &amp;lt;log4net&amp;gt;
        &amp;lt;!-- Define some output appenders --&amp;gt;
        &amp;lt;appender name=&quot;rollingFile&quot; type=&quot;log4net.Appender.RollingFileAppender,log4net&quot; &amp;gt;
            &amp;lt;param name=&quot;File&quot; value=&quot;log.txt&quot; /&amp;gt;
            &amp;lt;param name=&quot;AppendToFile&quot; value=&quot;true&quot; /&amp;gt;
            &amp;lt;param name=&quot;RollingStyle&quot; value=&quot;Date&quot; /&amp;gt;
            &amp;lt;param name=&quot;DatePattern&quot; value=&quot;yyyy.MM.dd&quot; /&amp;gt;
            &amp;lt;param name=&quot;StaticLogFileName&quot; value=&quot;true&quot; /&amp;gt;
            &amp;lt;layout type=&quot;log4net.Layout.PatternLayout,log4net&quot;&amp;gt;
                &amp;lt;param name=&quot;ConversionPattern&quot; value=&quot;%d [%t] %-5p %c [%x] (%X{auth}) - %m%n&quot; /&amp;gt;
            &amp;lt;/layout&amp;gt;
        &amp;lt;/appender&amp;gt;
        &amp;lt;root&amp;gt;
            &amp;lt;!-- priority value can be set to ALL|INFO|WARN|ERROR --&amp;gt;
            &amp;lt;priority value=&quot;INFO&quot; /&amp;gt;
            &amp;lt;appender-ref ref=&quot;rollingFile&quot; /&amp;gt;
        &amp;lt;/root&amp;gt;
    &amp;lt;/log4net&amp;gt;
&amp;lt;/configuration&amp;gt;
  
 在 public/web.config 裡面，註冊 service： 
&amp;lt;monorail&amp;gt;
    &amp;lt;services&amp;gt;
        &amp;lt;service 
            id=&quot;Custom&quot; 
            interface=&quot;Castle.Core.Logging.ILoggerFactory, Castle.Core&quot;
            type=&quot;Castle.Services.Logging.Log4netIntegration.Log4netFactory, Castle.Services.Logging.Log4netIntegration&quot; /&amp;gt;
    &amp;lt;/services&amp;gt;
    &amp;lt;!--略...--&amp;gt;
   
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/4784799.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 07 Jan 2008 17:10:01 +0800</pubDate>
					</item>
	<item>
		<title>Monorail ActiveRecord Scaffold / Thinking more...</title>
		<description>今天看官方文件時，看到這個： ActiveRecord Scaffold  
只要有 model，monorail 可以自動幫你把 controller configure 成有 scaffold 功能 (CRUD都具備) 的 controller：
 
[Scaffolding( typeof(Blog) )]
public class BlogsController : Controller
{
}
 
 
這真是令人驚訝...不過 rc2 預設的 Layout 有問題，所以你最好加上 [Layout] attribute，自訂 Layout 比較好... 
缺點是，要作 localization 的話，依照現在 rc2 的代碼，根本不可能... 
 
結論是，有空可以來看看這邊的代碼(ARFormHelper.cs/PresentationHelper.cs)，因為 Generator 裡面的 ScaffoldHelper 有些情況沒考慮的很仔細。 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/4770977.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 04 Jan 2008 16:40:44 +0800</pubDate>
					</item>
	<item>
		<title>How to monorail by Generator tool(4) / Thinking more...</title>
		<description>在研究過之後，我決定在 ScaffoldHelper.cs 裡面添加 GetText 這個函數，用來取得字串。
 
    #region Localization helpers
    public string GetText( IResource resource, string str )
    {
        if( resource==null )
            return str;
        
        object resStr = resource[ str ];
        if( resStr==null )
            return str;
        
        return resStr.ToString();
    }
    #endregion
 
這樣在 .vm (template)檔案裡面，就可以這麼使用，以取得本地化後的字串：
 
$ScaffoldHelper.GetText($textres, &quot;Name&quot; )
 
當然你還是可以用原先的方法：
 
$textres.Name
 

所以 PageBrowser() 也可以跟著修正為：
 
    #region Pagination helpers
    public string PageBrowser( Page page )
    {
        return PageBrowser( page, null );
    }
        
    public string PageBrowser( Page page, IResource resource )
    {
        StringWriter output = new StringWriter();
        PaginationHelper helper = new PaginationHelper();
        helper.SetController(this.Controller);
        string firstText = GetText( resource, &quot;First&quot; );
        string prevText = GetText( resource, &quot;Previous&quot; );
        string nextText = GetText( resource, &quot;Next&quot; );
        string lastText = GetText( resource, &quot;Last&quot; );
			
        if (page.HasFirst)
            output.Write(helper.CreatePageLink(1, firstText ));
        else
            output.Write( firstText );
	
        output.Write(&quot; | &quot;);
			
        if (page.HasPrevious)
            output.Write(helper.CreatePageLink(page.PreviousIndex, prevText ));
        else
            output.Write(prevText);
        
        output.Write(&quot; | &quot;);
        
        if (page.HasNext) 
            output.Write(helper.CreatePageLink(page.NextIndex, nextText ));
        else
            output.Write( nextText );
        
        output.Write(&quot; | &quot;);
        
        if (page.HasLast) 
            output.Write(helper.CreatePageLink(page.LastIndex, lastText ));
        else
            output.Write( lastText );
			
        return output.ToString();
    }
    #endregion
 

最後在資源檔裡面加上必要的字串並且修改 .vm (template)以後，就可以得到本土化後的結果。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/4727151.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 26 Dec 2007 16:55:30 +0800</pubDate>
					</item>
	<item>
		<title>How to monorail by Generator tool(3) / Thinking more...</title>
		<description>這一次要講的是 Localization，不幸的是 Generator 沒有考慮到 Localization 問題，所以由 Generator 產生出來的代碼，並不包含這部份，但這卻是一個很好的機會讓我去了解 Generator 與 monorail 底下的機制。 
 
 Castle 官方網站上已經有介紹該怎麼 Localization： Resources and Localization ，但不幸的是，他使用 Visual Studio.Net 作為範例，Visual Studio.Net 已經掩蓋了所有細節。
在研究官方文件與相關文件之後，以下是我的步驟。 
 
首先，你要先在 app/controllers 加上：
 
	[Resource(&quot;textres&quot;, &quot;ToDo.categories&quot;)]
 
這表示在 view(template) 那兒使用 $textres 就可以存取資源檔的內容。 
 
所以在 app/views/categories/list.vm 裡，就可以把必要的字串改用 $textres.字串名稱 替代掉，這裡我就不列出整個 list.vm 了，只列出幾行：
 
	&amp;lt;!--略--&amp;gt;
	$HtmlHelper.LinkTo( $textres.AddNewCategory, &quot;categories&quot;, &quot;new&quot;)
	&amp;lt;!--略--&amp;gt;
	$HtmlHelper.LinkTo( $textres.View, &quot;categories&quot;, &quot;view&quot;, $category.Id)
	&amp;lt;!--略--&amp;gt;
	$HtmlHelper.LinkTo( $textres.Edit, &quot;categories&quot;, &quot;edit&quot;, $category.Id)
	&amp;lt;!--略--&amp;gt;
	$AjaxHelper.LinkToRemote( $textres.Delete, &quot;delete.aspx&quot;, $DictHelper.CreateDict(&quot;with=&#039;id=$category.Id&#039;&quot;, &quot;condition=confirm(&#039;Delete?&#039;)&quot;, &quot;onsuccess=new Effect.Fade(&#039;category$category.Id&#039;)&quot;))
	&amp;lt;!--略--&amp;gt;
 

然後我選擇在 app/ 下建立一個 resources 目錄，用來放置資源檔：
 
;Filename: categories.txt
;Language: en-US
View=View
Edit=Edit
Delete=Delete
AddNewCategory=Add a new Category
 
 
;Filename: categories.zh-tw.txt
;Language: zh-tw
View=檢視
Edit=編輯
Delete=刪除
AddNewCategory=加新類別
 
這裡要特別注意，把文字檔的編碼存為 unicode 或是 utf-8，否則會有亂碼出現。 
 
最後修改 default.build，以便把資源檔編譯進去，這裡我也只列出關鍵的幾行：
 
	&amp;lt;!--略--&amp;gt;
	&amp;lt;target name=&quot;build&quot; description=&quot;Compile all source files&quot;&amp;gt;
		&amp;lt;mkdir dir=&quot;${dir.bin}&quot; /&amp;gt;
		&amp;lt;copy flatten=&quot;true&quot; todir=&quot;${dir.bin}&quot;&amp;gt;
			&amp;lt;fileset&amp;gt;
				&amp;lt;include name=&quot;${dir.lib.castle}/**&quot; /&amp;gt;
				&amp;lt;include name=&quot;${dir.lib.npgsql}/**&quot; /&amp;gt;
				&amp;lt;include name=&quot;${dir.lib.mysql}/**&quot; /&amp;gt;
				&amp;lt;include name=&quot;${dir.lib.migrator}/**&quot; /&amp;gt;
				&amp;lt;include name=&quot;${dir.lib.nunit}/nunit.framework.dll&quot; /&amp;gt;
			&amp;lt;/fileset&amp;gt;
		&amp;lt;/copy&amp;gt;
		&amp;lt;resgen todir=&quot;${dir.src.app}/resources/&quot;&amp;gt;
			&amp;lt;resources&amp;gt;
				&amp;lt;include name=&quot;${dir.src.app}/resources/*.txt&quot; /&amp;gt;
			&amp;lt;/resources&amp;gt;
		&amp;lt;/resgen&amp;gt;
		&amp;lt;csc target=&quot;library&quot; output=&quot;${dir.bin}/${project::get-name()}.dll&quot;&amp;gt;
			&amp;lt;sources&amp;gt;
				&amp;lt;include name=&quot;${dir.config}/Boot.cs&quot; /&amp;gt;
				&amp;lt;include name=&quot;${dir.src.app}/**/*.cs&quot; /&amp;gt;
				&amp;lt;include name=&quot;${dir.src.test}/**/*.cs&quot; /&amp;gt;
				&amp;lt;include name=&quot;${dir.migrations}/**/*.cs&quot; /&amp;gt;
			&amp;lt;/sources&amp;gt;
			&amp;lt;resources basedir=&quot;.&quot; prefix=&quot;ToDo&quot;&amp;gt;
				&amp;lt;include name=&quot;${dir.src.app}/resources/*.resources&quot;/&amp;gt;
			&amp;lt;/resources&amp;gt;
			&amp;lt;references basedir=&quot;${dir.bin}&quot;&amp;gt;
				&amp;lt;include name=&quot;System.Web.dll&quot; /&amp;gt;
	&amp;lt;!--略--&amp;gt;
 
最重要的就是 resgen 這個區塊與 csc 裡面的 resources 區塊，resgen 是把文字檔轉換為 .resources 資源檔，而 csc 裡面的 resources 則是表示要把產生出來的 .resources 編譯進去。 
 
好了，該修改的都修改了，接下來就是重新建立，輸入 nant 就會自動重新編譯。 
有點美中不足的是，下面顯示頁次的部份仍然是英文，這是因為這些字串被寫死在 ScaffoldHelper.cs 裡面，我想下次再來修改這部份。 
 
後記：  csc resources 所指定的 prefix 與 [Resource(&quot;textres&quot;, &quot;ToDo.categories&quot;)] 的第二個參數息息相關，不妨修改來試試看。  網站文件有提到 LocalizationFilter 的部份，但是用了卻不行，有待繼續研究。  
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/4722367.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 25 Dec 2007 16:54:39 +0800</pubDate>
					</item>
	<item>
		<title>How to monorail by Generator tool(2) / Thinking more...</title>
		<description>接下來，就參考這篇有名的  Four Days on Rails  來試試看吧～ 
首先呢，由於隔了這麼久才寫這篇，所以 Generator 改位置了，你得從這裡： http://svn.castleproject.org:8080/svn/castle/trunk/Experiments/Generator/  Checkout，其他大致都跟上篇一樣。 
 
  先利用 monorail ToDo，建立專案，接著依照上篇文章作必要的設定，同時我們使用 rc2，不使用最新的版本(也就是你不用更動 default.build)，設定的部份就不再贅述。  建立資料庫，這邊我是用 MySQL ，建立的資料庫名稱是 ToDoDev，不過這只有跟修改連線字串有關係。  修改資料庫的連線字串，連線字串是放在 config/databases/ 下的 ActiveRecord 設定檔裡面，你可以看到這邊有兩個設定檔，他很貼心的把開發用與測試用的資料庫分開：development.xml、test.xml，事實上，你還可以增加一個 Production (或是其他名字)的 ActiveRecord 設定檔，表示這是正式上線用的資料庫。切換的時候，可以更動 config/boot.cs 以決定使用哪個 ActiveRecord 設定檔，預設是 development。  建立 Model，首先先產生&quot;Category&quot;，Category 的欄位如下：   id int autoincrement 
  name varchar(255) 
  created_on datetime 
  updated_on datetime 
 ，在專案的目錄下輸入：script\generate model Categories name created_on updated_on，這邊要注意的是，不需要特別寫 id，因為慣例至上，Generator會自動幫你增加 Id 這個欄位。Generator 會幫你作三件事情：產生 Category 這個類別、產生測試 Category 的 Unit test 類別以及建立資料表格的程式，你可以從指令的輸出結果很清楚的看到。     exists app\models 
    create app\models\Categories.cs 
    exists test\models 
    create test\models\CategoriesTest.cs 
    create db\migrations 
    create db\migrations\001_AddCategoriesTable.cs 
   接下來，要去修改 Categories 類別的屬性型態，Generator 預設都是把型態設為字串，db\migrations 那邊則都是建立 varchar(50)。所以除了 app\models\Categories.cs 要修改型態之外，db\migrations\001_AddCategoriesTable.cs 下也要改！這邊把 Name 改為 255 個字元，created_on與updated_on 則改為 DateTime。  都修改完畢之後，就可以執行 nant migrate，這個步驟會幫你去實體資料庫作必要的事情。為甚麼要這樣子作？我想是因為一般資料庫的 script 是沒有作管理的，因此，才刻意把這些要去資料庫建立表格、修改欄位等的動作都放到 db\migrations 下，以便把這些程式也都納入版本控制。  執行 script\generate scaffold Category，這個步驟會一口氣幫你把 CRUD 的頁面都弄出來。  那麼，就編譯吧，直接執行 nant，只是卻出現了... [csc] app\controllers\CategoriesController.cs(36,72): error CS0246: 找不到型別或命名空間名稱 &#039;Category&#039; (您是否遺漏 using 指示詞或組件參考?) 
[csc] app\controllers\CategoriesController.cs(56,45): error CS0246: 找不到型別或命名空間名稱 &#039;Category&#039; (您是否遺漏 using 指示詞或組件參考?)
 這個，得去修改 CategoriesController.cs，把 Category 都改為 Categories，這看來是 Generator 的問題。接著又再出現
 error CS1501: 方法 &#039;CreatePagination&#039; 沒有任何多載使用 &#039;2&#039; 個引數 ，唉～這個錯誤訊息實在是太黯然又太銷魂...你必須再次修改 CategoriesController.cs，添加這兩行：
 using System.Collections;
using System.Collections.Generic;
 然後把  PropertyBag[&quot;categories&quot;] = PaginationHelper.CreatePagination( Categories.FindAll(), 10); 改為
 PropertyBag[&quot;categories&quot;] = PaginationHelper.CreatePagination( (IList)Categories.FindAll(), 10); ，接下來應該就沒問題了。  先試試看到目前為止的成果吧，輸入script\server，然後打開你的瀏覽器，在位址列輸入：http://localhost:8080/categories/list.aspx，就能看到結果了。  
 
執行結果：
   
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/4693005.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 20 Dec 2007 14:53:35 +0800</pubDate>
					</item>
	<item>
		<title>Gtk# UI設計隨便聊 / Thinking more...</title>
		<description>前一陣子用 MonoDevelop 來寫 Gtk# 應用程式玩，發現真的是很簡單。
幾乎可以跟  SharpDevelop  或 Visual Studio.Net 設計 Windows form 應用程式一樣了，同樣也是拖拉放，就可以完成。

對於初入門的人來說，最痛苦的可能還是對於 Gtk# 的物件模型不熟悉，因為不熟悉，所以也就不知道該去處理哪些屬性與事件。
好在 Mono 官方網站有提供入門文件：   GtkSharp系列文件    Beginners Guide   用力唸一唸這些文件跟自己去嘗試，大致上應該是夠了。但這些文件大部分都是自己去寫 Layout code。

如果你正在使用目前版本的  MonoDevelop  在 Layout 的話，你會發現世界全然不同，因為 MonoDevelop 引進了  Stetic 。
現在使用  MonoDevelop  拉出來的 Form，實際上都會被存放在專案目錄下的 gtk-gui 目錄下的某個 xml 檔案，在每次 build 之前， MonoDevelop  會先把 xml 轉換為一個存放於 gtk-gui 目錄下的 partial 類別(.cs)，然後 build 的時候，再 build 到一起。而在專案目錄下所看到的代碼，只會有一行 Build()。
這真的是方便很多，開發者只需要專注於如何處理程式邏輯就可以，而不需要去管 UI 代碼的生成。

在  MonoDevelop  加入  Stetic  之前，大部分的 Gtk# 應用程式還是用手動加代碼或是用 Glade# 來設計介面（詳細的 Glade# 用法，可以參考  Your First Glade# Application  的說明）。
Glade# 其實也是把整個 UI 存成一個 xml 檔案，所以你得先使用 Glade 應用程式設計出 UI，得到 .glade 檔案，然後在程式裡面：  載入 .glade 檔案  為控制項(Widget)加上 Attribute  撰寫事件處理並繫結  。
這當然是比手動寫代碼方便許多，但比起  Stetic ，還是要多作事，往往用 Glade 修改 UI 後，可能會忘記加必要的 Widget 宣告，或是對應的事件繫結。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/4674857.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 18 Dec 2007 16:48:51 +0800</pubDate>
					</item>
	<item>
		<title>Gtk.TreeView(3) / Thinking more...</title>
		<description>在 Linux 裡面，所謂的&quot;事件&quot;，多半是用 Signal 來表示，所以你看到 Signal 時，可以概略地當作&quot;事件&quot;來看。 
而這些事件跟 Windows Form 的事件命名法差異相當大。 
以下這些是比較常用到的：     protected virtual void OnTreeview1RowActivated (object o, Gtk.RowActivatedArgs args)
    {
        // double click
        Console.WriteLine( String.Format(&quot;[{0}]: {1}&quot;, o.GetType().ToString(), &quot;row activated&quot;) );
    }
    
    protected virtual void OnTreeview1RowCollapsed (object o, Gtk.RowCollapsedArgs args)
    {
        // collapse
        Console.WriteLine( String.Format(&quot;[{0}]: {1}&quot;, o.GetType().ToString(), &quot;row collapsed&quot;) );
    }
    
    protected virtual void OnTreeview1RowExpanded (object o, Gtk.RowExpandedArgs args)
    {
        // expand
        Console.WriteLine( String.Format(&quot;[{0}]: {1}&quot;, o.GetType().ToString(), &quot;row expanded&quot;) );
    }
    
    protected virtual void OnTreeview1CursorChanged (object sender, System.EventArgs e)
    {
        // click
        Console.WriteLine( String.Format(&quot;[{0}]: {1}&quot;, sender.GetType().ToString(), &quot;Cursor changed&quot;) );
    }
 
 
我是怎麼查到的呢？ 
坦白說，我是用笨方法，看到那些 Console.WriteLine 了沒？ 
我先試著在可能的事件裡面放置這些 Console.WriteLine，接著執行程式，試著去 Click、Expand，然後看 Console 輸出就知道了...
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/4662027.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 17 Dec 2007 10:08:34 +0800</pubDate>
					</item>
	<item>
		<title>Gtk.TreeView (2) / Thinking more...</title>
		<description>根據昨天的程式，稍作改良，就可以把整個目錄樹丟進去顯示了... 
下面就是利用 Recursive 來把資料塞到 TreeStore 裡面去。 
 
 
	public void _buildTreeStore( TreeStore store, DirectoryInfo di, TreeIter parent )
	{
		foreach( DirectoryInfo iter in di.GetDirectories() )
		{
			TreeIter ti = store.AppendValues( parent, iter.FullName, iter.Name, &quot;&quot; );
			_buildTreeStore( store, iter, ti, true  );
		}
		// add files in tree
		foreach( FileInfo fi in di.GetFiles() )
			store.AppendValues( parent, fi.FullName, fi.Name, fi.Length.ToString() );
	}
	
	public TreeStore buildTreeStore( string path )
	{
		// 0: fullpath 1: name 2: filesize
		TreeStore store = new TreeStore( typeof(string), typeof(string), typeof(string) );
		DirectoryInfo di = new DirectoryInfo( path );
		TreeIter root = store.AppendValues( path, di.Name, &quot;&quot; );
		_buildTreeStore( store, di, root );
		return store;
	}

	public ExplorerSharp(): base(Gtk.WindowType.Toplevel)
	{
		Build();

		TreeStore store = buildTreeStore( &quot;./&quot; );

		// 設定資料來源  
		treeview1.Model = store;  

		// 不顯示表頭  
		treeview1.HeadersVisible = false;  

		// 設定要顯示的欄位  
		treeview1.AppendColumn(&quot;Name&quot;, new CellRendererText(), &quot;Name&quot;, 1 );  
		treeview1.AppendColumn(&quot;Size&quot;, new CellRendererText(), &quot;FileSize&quot;, 2 );  

		// 一次只能選定一列或一個節點  
		treeview1.Selection.Mode = Gtk.SelectionMode.Single;  
	}
 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/4629083.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 12 Dec 2007 17:19:18 +0800</pubDate>
					</item>
	<item>
		<title>Gtk.TreeView (1) / Thinking more...</title>
		<description>使用 TreeView 的基本，首先就是添加列與設定要顯示的欄。 
呈現的方式，取決於你給 TreeView.Model 屬性的資料是什麼，如果是 TreeStore，就會顯示 Tree，如果是 ListStore，就會顯示 Grid。 
 
 
    // 如果你把 TreeStore 改為 ListStore，就能得到類似 Grid 的效果。
    TreeStore store = new TreeStore();
    for( int i=0; i 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/4615599.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 11 Dec 2007 15:58:08 +0800</pubDate>
					</item>
	<item>
		<title>Gtk.TreeView / Thinking more...</title>
		<description>這幾天玩 MonoDevelop  Stetic (gtk# 的 UI designer) 的時候，發現 gtk# 裡的 TreeView Widget 是個很有趣的元件。
有趣的原因，是因為他的設計哲學整個跟 Windows form 的設計哲學截然不同，Windows form 的 TreeView 就是很單純的 TreeView，沒別的。
而 gtk# 的 TreeView Widget 則是以所謂的 MVC Pattern 去設計，所以，其實 TreeView Widget 會根據你塞進去的 Store (Model) 來決定該怎麼去顯示。也因此，它既可以當作 Grid 來用，也可以當作 TreeView 來用，也可以當作有 TreeView 的 Grid 來用。
摸索的時候，花了不少時間，但今天打算寫這篇的時候，發現 Mono 官方網站就有 Tutorial： GtkSharp TreeView Tutorial ，真的是白白浪費了摸索的時間...
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/4596589.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Sat, 08 Dec 2007 17:12:14 +0800</pubDate>
					</item>
	<item>
		<title>如何在 Ubuntu/Debian 下重新編譯 mono/monodevelop / Thinking more...</title>
		<description>謝謝你，Dale E. Moore： [MonoDevelop] Can&#039;t keep monodevelop running 
信內所提供的方法，真是相當簡單又快速，也讓我學到 apt-get 的另外一個用法：build-dep
 
sudo apt-get build-dep mono monodevelop
Download mono-1.2.5.2.tar.bz2&amp;lt;http://go-mono.com/sources/mono/mono-1.2.5.2.tar.bz2&amp;gt;and monodevelop-0.17.tar.bz2&amp;lt;http://go-mono.com/sources/monodevelop/monodevelop-0.17.tar.bz2&amp;gt;from http://go-mono.com/sources-stable/.

bunzip2 mono-1.2.5.2.tar.bz2
tar xvf mono-1.2.5.2.tar.bz2
cd mono-1.2.5.2
./configure --prefix=`pkg-config --variable=prefix mono`
make
sudo make install

bunzip2 monodevelop-0.17.tar.bz2
tar xvf monodevelop-0.17.tar
cd monodevelop-0.17
./configure --prefix=`pkg-config --variable=prefix mono`
make
sudo make install
 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/4557817.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 29 Nov 2007 12:30:26 +0800</pubDate>
					</item>
	<item>
		<title>.Net framework 2.0 SP1/3.0 SP1/3.5 無法安裝 / Thinking more...</title>
		<description>前一陣子 Microsoft 釋出了Visual Studio 2008/.Net framework 3.5，前兩天想裝起來看看，只是怎麼裝都不行。
經過與 Google 明查暗訪的結果，都說要先移除掉先前安裝的所有 .Net frameowrk以及登錄檔(Registry)裡面的資訊，再重新安裝才行。
還好， Microsoft 的 Aaron Stebner 寫了一個 工具 ，可以幫你作掉這些麻煩事，也因為這個工具，我先移除了先前安裝的 .Net framework 3.0，再移除掉 .Net framework 2.0，接著依序安裝 .Net framework 2.0 SP1、.Net framework 3.0 SP1、.Net framework 3.5，就大功告成了。

關於這個工具的文章與下載網址： Aaron Stebner&#039;s WebLog : Automated cleanup tool to remove the .NET Framework 1.0, 1.1, 2.0, 3.0 and 3.5 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/4553349.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 28 Nov 2007 17:48:52 +0800</pubDate>
					</item>
	<item>
		<title>新版 mod_mono 在啟動時的警告 / Thinking more...</title>
		<description>最近在重新啟動 Apache httpd 時，常出現這錯誤訊息(我的環境：CentOS 4.5)：
 Starting httpd: [Tue Oct 30 07:39:41 2007] [crit] The unix daemon module not initialized yet. Please make sure that your mod_mono module is loaded after the User/Group directives have been parsed. Not initializing the dashboard.
 

今天早上認真地向 Google 祈禱了一下，發現有人問過了： [Mono-list] Errors after update....:( 
解決方法很簡單，就是打開你的 httpd.conf，確定 User apache
Group apache 
在 Include conf.d/*.conf 之前即可。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/4390155.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 30 Oct 2007 07:45:03 +0800</pubDate>
					</item>
	<item>
		<title>How to monorail by Generator tool(1) / Thinking more...</title>
		<description>環境：Windows 2000/XP
需求：   Subversion (或 TortoiseSVN    NAnt    Mono ，主要是要裡面的 boo  
  利用 Subversion (或 TortoiseSVN  checkout Generator 出來，網址： http://svn.castleproject.org:8080/svn/castle/trunk/Tools/Generator/ 。  進行編譯與安裝：nant install，這個步驟會將 monorail.bat 與 generator.bat 這兩個批次檔安裝到 c:\winnt 或 c:\windows 下。  切換到你的工作目錄，執行 monorail your_project，就會自動幫你產生出 your_project 這個目錄，裡面就是完整的框架。  切換到 your_project 目錄下，執行 nant setup，這個步驟會自動幫你下載官方網站上的 rc2 版本下來進行設定，如果你想要使用最新的組件，可以修改 default.build 裡面的 castle.url，將他改為 官方 build server  上提供的網址(每日更新)，如： &amp;lt;property name=&quot;castle.url&quot; value=&quot;http://builds.castleproject.org/builds/castleproject-1.1-build_456-net-2.0-debug.zip&quot; /&amp;gt; ；或是本地端位置  &amp;lt;property name=&quot;castle.url&quot; value=&quot;file://c:\download\Castle-net-2.0-debug-2007-7-30 (r4074).zip&quot; /&amp;gt;   修改 public/web.config，第18行多了 &amp;lt;services&amp;gt; 將這行移除或註解掉。  將  Mono  目錄下的 booi.bat 複製到 your_project 目錄下，script 目錄下的批次檔都會用到，所以複製到這邊以後會比較省事。  修改 script\server.bat為如下內容，如果你不修改的話，Webdev.WebServer.exe 雖然可以順利執行，但卻會出錯。 @booi script\server.boo %windir%\Microsoft.NET\Framework\v2.0.50727\Webdev.WebServer.exe norestart /port:8080 /path:%CD%\public   執行 script\server，右下角會有 Webdev.WebServer.exe 的 trayicon 出現，告訴你可以用了。打開瀏覽器吧，在網址列輸入 http://localhost:8080/index.html 就可以看到畫面囉～  

除了以上的步驟，產生出來的專案目錄下有個 README.TXT，你也可以好好地閱讀一下。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/3850251.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 02 Aug 2007 08:00:50 +0800</pubDate>
					</item>
	<item>
		<title>ActiveRecord SessionScope/Transaction / Thinking more...</title>
		<description> ActiveRecord 是很方便沒錯，只是如果你要處理大量時，底層的 NHibernate 會以你意想不到的方式去逐條更新資料表格，可想而知，這很慢～
幸好官方有提供了文件( Using Scopes :: Castle Project ,  Understanding Scopes :: Castle Project )，告知你如何利用SessionScope來完成批次處理，也就是先行處理完畢以後，再一次寫入，這樣子速度就可以達到一定程度的提昇。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/3724915.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 27 Jul 2007 14:33:48 +0800</pubDate>
					</item>
	<item>
		<title>如何使用 Mono.GetOptions？ / Thinking more...</title>
		<description>Mono.GetOptions 是做什麼的？問的好。 
如果你曾經在 Linux 下開發過 console 應用程式，相信你對於 getopt 這個 library 應該不陌生才對。 
Mono.GetOptions 就是一個類似  getopt  的組件。 
 
這裡主要是介紹怎麼使用，下面就列出步驟：
  安裝 Mono 。  在 AssemblyInfo.cs 裡面加入： //填入簡單的用法說明，顯示 help 時會用到
[assembly: Mono.UsageComplement(&quot;[-t:param] [-o] [-h] [-v] [-u]&quot;)]
//填入關於這程式的說明，也是顯示 help 時會用到
[assembly: Mono.About(&quot;A sample about how to use Mono.GetOptions&quot;)]
//作者
[assembly: Mono.Author(&quot;your_name&quot;)]
//有錯誤時可以通報誰，可填可不填
[assembly: Mono.ReportBugsTo(&quot;your_name@your_domain.com&quot;)]
//更詳細的說明，可填可不填
[assembly: Mono.AdditionalInfo(&quot;This is a sample about how to use Mono.GetOptions.  It&#039;s only a small program.  If you want to know more about Mono.GetOptions, you can hack Mono.GetOptions source code.&quot;)]
//是屬於哪個套件，可填可不填
[assembly: Mono.IsPartOfPackage(&quot;Samples&quot;)]
 然後在原來的地方應該會有這些： [assembly: AssemblyTitle(&quot;Mono.GetOptions Sample&quot;)]
[assembly: AssemblyProduct(&quot;getoptions_sample&quot;)]
[assembly: AssemblyCopyright(&quot;your_name or your_organization&quot;)]
[assembly: AssemblyVersion(&quot;1.0.*&quot;)]
 請記得都填入。  引用 Mono.GetOptions 組件，用 SharpDevelop 的話，可以很方便的選 Add mono reference。  記得 using Mono.GetOptions。 using Mono.GetOptions;   新增一個類別，繼承 Options。 using System.Collections.Generic;
class ProgramOptions : Options
{
	private string _outputFolder = &quot;output&quot;;

	public string OutputFolder
	{
		get { return _outputFolder; }
		set { _outputFolder = value; }
	}

	private List  _templateFolders;

	// 表示最多容許兩個，參數可以用 -t 或是 --template
	// 用法大致是 -t:test 或 --template:test
	[Option(2, &quot;Template folder, default is &#039;default&#039;&quot;, &#039;t&#039;, &quot;template&quot;)]
	public WhatToDoNext DoTemplate( string s )
	{
		//Console.WriteLine( &quot;template={0}&quot;, s );
		_templateFolders.Add( s );
		return WhatToDoNext.GoAhead;
	}

	// 預設只容許一個，參數是 -o 或 --output
	[Option(&quot;Output folder, default is &#039;output&#039;&quot;, &#039;o&#039;, &quot;output&quot;)]
	public WhatToDoNext DoOutput( string s )
	{
		//Console.WriteLine( &quot;output={0}&quot;, s );
		_outputFolder = s;
		return WhatToDoNext.GoAhead;
	}

	public ProgramOptions()
	{
		// 表示同時接受 Linux / Windows 的命令列常態用法
		this.ParsingMode = OptionsParsingMode.Both;

		_templateFolders = new List ();
	}
}
   在 Main 裡面使用剛剛新增的類別： ProgramOptions options = new ProgramOptions(); 
options.ProcessArgs(args);
foreach( string s in options.TemplateFolders )
	Console.WriteLine( &quot;Template folder = {0}&quot;, s );
Console.WriteLine( &quot;Output folder = {0}&quot;, options.OutputFolder );
 就這麼簡單。  Build 以後，你可以在命令列模式或是 linux 的 console 模式下試試看了～這邊我假設你編譯出來的目的檔是 your_program： #your_program -h
#your_program --help
#your_program --template:t1 --template:t2 --output:o1
#your_program -t:t1 -t:t2 -o:o1
#your_program -u
#your_program -V
#your_program --version
   
 
對 getopt 有興趣的話，可以參考 getopt 。 
這是對岸同志寫的介紹，很簡短：  Mono项目提供的一个控制台程序辅助包GetOptions - 自由、创新、研究、探索…… - 博客园   
這篇也是 Tutorial，寫的很好： The PumaCode.org Blog :: GetOpt style command line processing in C# with Mono.GetOptions  
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/3605181.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 06 Jul 2007 14:14:54 +0800</pubDate>
					</item>
	<item>
		<title>如何在 CentOS 4/4.5 裡安裝 mono / Thinking more...</title>
		<description>這裡，我假設你用 yum 來管理你的套件。

  下載  mono.repo  然後放到 /etc/yum.repos.d/ (以 root 身份)  #yum update  #yum install mono-complete xsp mod_mono  完成啦!  

很簡單，對吧～
如果你用 Fedora Core 3/4/5 或者是 RHEL 4，你可以參考 Mono 下載頁面 。
安裝的方法跟上面所說得非常地類似。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/3552733.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 29 Jun 2007 16:20:33 +0800</pubDate>
					</item>
	<item>
		<title>ActiveRecord 的除錯 / Thinking more...</title>
		<description>老實說，這還真令人困擾，還好官方有說明如何得到更詳細的除錯資訊： Troubleshooting :: Castle Project 。
基本上，就是加上一些設定，於是 NHibernate  能根據這份設定以及內部有用到的  log4net  library把一些訊息丟到 log 裡面去。
靠著產出出來的 log，終於找到問題。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/3426043.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 07 Jun 2007 13:49:56 +0800</pubDate>
					</item>
	<item>
		<title>樂透下期號碼預測(3)-完結 / Thinking more...</title>
		<description>為甚麼沈寂了這麼久才寫這篇，那是因為我發現，樂透是不可預測的。其實有學過統計學的我早應該知道了。
如果你還是想試試看預測，那麼可以參考這一系列排列組合的文章，應該會很有幫助：
   瓶水相逢:C# - P(n, r) 排列組合問題 - 樂多日誌    瓶水相逢:C# - 產生 Permutation - P(n) 排列問題 - 樂多日誌    瓶水相逢:C# - 產生 Combination - C(n, r) 組合問題 - 樂多日誌    瓶水相逢:C# - 產生 Power Set - 樂多日誌   
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/3397425.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 04 Jun 2007 11:49:34 +0800</pubDate>
					</item>
	<item>
		<title>Porting guide / Thinking more...</title>
		<description>今天看到 jpobst 的 這篇文章：Porting Guide 。
他說，他上星期在 Mono wiki 上寫了一篇 Guide: Porting Winforms Applications ，內文提到如何將 NClass 移植到 Linux Mono 上的過程。
整個移植的過程相當簡單，首先利用 MoMA (Mono Migration Analyzer) 去分析 NClass ，得知 NClass 使用了哪些類別，而這些類別(內部的method)在 Mono 裡面是否已經被實做、有沒有使用 P/Invoke 等技術等等，接著再去補足 Mono 的類別或改寫 NClass(別忘記寄patch給原作者啊)，這樣就完成整個移植的過程。
對於想把 Windows 上的 .Net 應用程式移植到 Linux 的人，這是一篇相當具有參考性的文章。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/3344443.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 25 May 2007 10:33:52 +0800</pubDate>
					</item>
	<item>
		<title>ActiveRecord / Thinking more...</title>
		<description> ActiveRecord 是一套相當不錯的 Pattern library，主要是實做 ActiveRecord pattern ，底層則是 NHibernate 。
大致的原理主要是在 Entity class 的屬性上加上 Attribute，Pattern 再根據這些資訊與設定來作  Object-relation mapping 。

官方網站提供了一份很簡潔的指引： Getting started with ActiveRecord 
很簡單，也很清楚，但是如果你想要更深入了解一些的話，我建議不妨參考 大陸網友Yuhen 的這一系列文章：   [ActiveRecord] 之一：初始化和配置 - Q.yuhen    [ActiveRecord] 之二：常用方法 - Q.yuhen    [ActiveRecord] 之三：SessionScope - Q.yuhen    [Castle AR] 4. CRUD - Q.yuhen    [Castle AR] 5. Base Relations - Q.yuhen   
或是 Oren Eini 的系列文章：   Castle Demo App: Getting Started With Active Record    Castle Demo App: Active Record Relations    Castle Demo App: Lazy Loading and Scopes    Castle Demo App: Many To Many Relations   
或是 Hamilton Verissimo 的系列文章：   All you wanted to know about Castle ActiveRecord - Part I    All you wanted to know about Castle ActiveRecord - Part II   

我覺得都寫的相當不錯。

原本官方有提供很不錯的工具： ActiveRecord Generator ，可以幫你從建好的 Database schema 去產生 entity class，省去你手動寫 code 的痛苦。
只是現在因為人力不足的關係，暫時停止繼續開發。

如果你想試試看所謂的 ORM ，不妨試試看這個 Library，可以讓你少寫掉很多很多 code。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/3338939.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 24 May 2007 17:03:43 +0800</pubDate>
					</item>
	<item>
		<title>tf4mono / Thinking more...</title>
		<description>原來早已經有非微軟官方釋出的 Team Foundation Server 的 client 端工具了～
這樣子不管是在 Linux 下或是在不想使用微軟官方 client 的情況下，都可以方便的去存取  CodePlex  的 Repository 了。

網址在這裡： tf4mono 

目前只有提供 Console mode 的指令，作者希望未來可以提供  MonoDevelop  的 Add-In...

消息來源：   Rope on Fire: tf4mono version 0.4.4    Team Foundation for Mono - Mono Project News   </description>
		<link>http://blog.roodo.com/thinkingmore/archives/3282655.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 21 May 2007 11:23:58 +0800</pubDate>
					</item>
	<item>
		<title>Visual WebGui (VWG) / Thinking more...</title>
		<description>今天在 Mono-dev 群組上看到有人詢問是否有類似 GWT 的軟體，可以快速開發 .Net 上的 ajax 程式。
 Miguel 大大 回答到有這麼一套： Visual WebGui (VWG)  

有空的話，來試試看好不好用。</description>
		<link>http://blog.roodo.com/thinkingmore/archives/3282643.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Sun, 20 May 2007 11:19:49 +0800</pubDate>
					</item>
	<item>
		<title>利用 Gmail SMTP server 來寄信 / Thinking more...</title>
		<description>詳情可以參考 這篇：Send E-Mail from your .NET application using your GMail Account ，內文提供了 .Net 1.1/2.0 的方法。 
 
我自己用 .Net 2，試的結果，發現有這個錯誤訊息出現：&quot;Must issue a STARTTLS command first&quot; 
Google 大神告訴我， 有蠻多人詢問這個問題 。 
仔細研讀之後，發現是我自己忘了幫 SmtpClient 設置 EnableSsl 屬性為 true。 
 
加上之後，又丟出 &quot;The requested feature is not implemented.&quot;。 
咦？沒實做，難道我用的 Mono  1.2.3.1還沒實做這部份？ 
用 Reflector 反組譯出來看之後，果然...真的還沒實做 SSL 傳輸的部份。 
希望下一版會加進去...這樣就可以在 Linux 下使用了。 
以下是程式碼，它是一個命令列的程式，讓你可以指定必要的欄位後寄送郵件。
打 MailSharp -h 可以得到使用說明。
 /**
 * MailSharp
 *
 * Reference:
 * 	Send E-Mail from your .NET application using your GMail Account - The Code Project - C# Programming &amp;lt;http://www.codeproject.com/useritems/SendMailUsingGmailAccount.asp&amp;gt;
 */
using System;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using System.Threading;
using System.ComponentModel;

namespace MailSharp {
public class MailSharpConsole {
    public static string showUsage() {
        StringBuilder sb = new StringBuilder();

        sb.AppendLine( &quot;Usage: MailSharp [options] ToAddress&quot; );
        sb.AppendLine( &quot;\t-a File to attach.&quot; );
        sb.AppendLine( &quot;\t-f From address&quot; );
        sb.AppendLine( &quot;\t-b Body message&quot; );
        sb.AppendLine( &quot;\t-s Subject&quot;);
        sb.AppendLine( &quot;\t-S SMTP server host&quot; );
        sb.AppendLine( &quot;\t-U Username for SMTP server authentication&quot; );
        sb.AppendLine( &quot;\t-p Password for SMTP server authentication&quot; );
        sb.AppendLine( &quot;\t-l Use SSL&quot; );
        sb.AppendLine( &quot;\t-h Help/Usage&quot;);
        sb.AppendLine();
        sb.AppendLine( &quot;Example:&quot; );
        sb.AppendLine( &quot;\tFor GMail&quot; );
        sb.AppendLine( &quot;\tMailSharp -f your_name@gmail.com -b Test -s Test -S smtp.gmail.com -P 587 -l -U your_gmail -p your_gmail_password someone@somewhere.com&quot; );

        return sb.ToString();
    }

    public static void Main(string[] args) {
        MailAddress from = null;
        MailAddress to = null;
        MailMessage message = new MailMessage();
        SmtpClient client = new SmtpClient();
        NetworkCredential myCred = new NetworkCredential();
        bool bShowUsage=false;

        try {
            if ( args.Length &amp;gt; 0 ) {
                for ( int i=0; i&amp;lt;args.Length; i++ ) {
                    switch ( args[i] ) {
                    case &quot;-S&quot;: // server host
                        i++;
                        if ( i&amp;lt;args.Length ) {
                            client.Host = args[i];
                        } else
                            throw new Exception( &quot;-S was specified, but no value.&quot; );
                        break;
                    case &quot;-P&quot;: // server port
                        i++;
                        if ( i&amp;lt;args.Length ) {
                            client.Port=Convert.ToInt32( args[i] );
                        } else
                            throw new Exception( &quot;-P was specified, but no value.&quot; );
                        break;
                    case &quot;-T&quot;: // timeout
                        i++;
                        if ( i&amp;lt;args.Length ) {
                            client.Timeout = Convert.ToInt32( args[i] );
                        } else
                            throw new Exception( &quot;-T was specified, but no value.&quot; );
                        break;
                    case &quot;-U&quot;: // username for smtp server authentication
                        i++;
                        if ( i&amp;lt;args.Length )
                            myCred.UserName = args[i];
                        else
                            throw new Exception( &quot;-U was specified, but no value.&quot; );
                        break;
                    case &quot;-p&quot;: // password for smtp server authentication
                        i++;
                        if ( i&amp;lt;args.Length )
                            myCred.Password = args[i];
                        else
                            throw new Exception( &quot;-p was specified, but no value.&quot; );
                        break;
                    case &quot;-l&quot;: // use SSL
                        client.EnableSsl = true;
                        break;
                    case &quot;-s&quot;: // subject
                        i++;	// next one is subject.
                        if ( i&amp;lt;args.Length ) {
                            message.Subject = args[i];
                            message.SubjectEncoding = System.Text.Encoding.UTF8;
                        } else
                            throw new Exception( &quot;-s was specified, but no value.&quot; );
                        break;
                    case &quot;-a&quot;:	// attachment
                        i++;	// next one is attachment filename.
                        if ( i&amp;lt;args.Length ) {
                            // Add attachment.
                            Attachment data = new Attachment( args[i], MediaTypeNames.Application.Octet);
                            message.Attachments.Add(data);
                        } else
                            throw new Exception( &quot;-a was specified, but no value.&quot; );
                        break;
                    case &quot;-b&quot;:	// body message.
                        i++;	// next one is body message
                        if ( i&amp;lt;args.Length ) {
                            message.Body = args[i];
                            message.BodyEncoding =  System.Text.Encoding.UTF8;
                        } else
                            throw new Exception( &quot;-b was specified, but no value.&quot; );
                        break;
                    case &quot;-f&quot;:	// from address
                        i++;
                        if ( i&amp;lt;args.Length ) {
                            // Specify the e-mail sender.
                            // Create a mailing address that includes a UTF8 character
                            // in the display name.
                            // from = new MailAddress( &quot;someone@gmail.com&quot;, &quot;someone&quot;, System.Text.Encoding.UTF8);
                            from = new MailAddress( args[i] );
                        } else
                            throw new Exception( &quot;-f was specified, but no value.&quot; );
                        break;
                    case &quot;-h&quot;:	// show help/usage
                        bShowUsage=true;
                        break;
                    default:
                        to = new MailAddress( args[i] );
                        break;
                    }
                }
            } else
                throw new Exception(&quot;No arguments.&quot;);
        } catch ( Exception ex ) {
            Console.WriteLine( ex.Message );
            bShowUsage = true;
        }

        try {
            if ( bShowUsage == true )
                throw new Exception( showUsage() );

            if ( from==null )
                throw new Exception( &quot;Must specify from address (-f).&quot; );

            // Set destinations for the e-mail message.
            if ( to == null )
                throw new Exception(&quot;At least, must specify to address&quot;);

            if ( client.Host == string.Empty )
                throw new Exception(&quot;Must specify SMTP Server (-S).&quot; );

            // Specify the message content.
            message.From = from;
            message.To.Add( to );

            // Credentials are necessary if the server requires the client
            // to authenticate before it will send e-mail on the client&#039;s behalf.
            //client.UseDefaultCredentials = false;
            client.Credentials = myCred;

            // Send.
            // If you need asynchronous sample, please visit the reference above.
            client.Send(message);

            Console.WriteLine(&quot;Done.&quot;);
        } catch ( Exception ex ) {
            Console.WriteLine( &quot;Exception was raised when sending...&quot;);
            Console.WriteLine( ex.Message );
        } finally {
            // Clean up.
            message.Dispose();
        }
    }
}
}
 
 
如果你打算在 Linux 下服用的話，可以搭配這個 script，免去你每次前面都要打 mono 的麻煩。
 #!/bin/sh
exec /usr/bin/mono $MONO_OPTIONS &quot;MailSharp.exe&quot; &quot;$@&quot;
 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/3216455.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 10 May 2007 15:09:44 +0800</pubDate>
					</item>
	<item>
		<title>Mono Cecil / Thinking more...</title>
		<description> 這篇文章：Using Cecil from IronPython 再次勾起我去年初看到  Mono.Cecil  時的回憶。
什麼是 Mono.Cecil ??以下翻譯自 Nauman Leghari&#039;s Blog : Fun with IronPython and Cecil ：
 &quot;Cecil 是由 Jb Evain ( http://evain.net/blog/ )所撰寫的類別庫，可以用來產生或注射自訂程序到以ECMA CIL撰寫的程序和類別庫。它提供了對泛型的完整支援以及對除錯資訊的部份支援。簡單的說好了，用了  Cecil ，你可以載入已經存在的組件，瀏覽裡面所有的型別，即時修改它們並保存修改過的組件。&quot; 

看起來是個很神奇的東西吧～這兩篇文章介紹了如何以 IronPython 去使用 Cecil ，是很不錯的指引文章：   Nauman Leghari&#039;s Blog : Fun with IronPython and Cecil    Nauman Leghari&#039;s Blog : Fun with IronPython and Cecil (Part II)   
此外也可以參考官方提供的 Cecil FAQ 。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/2954581.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 04 Apr 2007 09:55:36 +0800</pubDate>
					</item>
	<item>
		<title>如何存取SQLite / Thinking more...</title>
		<description>如果你還在找 SQLite 的 ADO.Net driver 的話，別找了。 
因為 Mono 就提供了一個： SQLite at Mono 。 
 
不管你是在 Windows 或是在 Linux 上，也不管你是用 Microsoft .Net Framework 或是 Mono，都可以直接拿他的 Mono.Data.SqliteClient.dll 來使用～ 
使用方法也很簡單：  連接字串：&quot;URI=file:/path/to/file,version=3&quot;。URI指定檔案位置，version則是指定SQLite database版本。  從使用範例可以看出，跟 .Net framework 提供的 ADO.Net driver 用法並沒有什麼差別(範例摘錄自 SQLite at Mono )：  using System;
using System.Data;
using Mono.Data.SqliteClient;

public class Test
{
    public static void Main(string[] args)
    {
       string connectionString = &quot;URI=file:SqliteTest.db&quot;;
       IDbConnection dbcon;
       dbcon = (IDbConnection) new SqliteConnection(connectionString);
       dbcon.Open();
       IDbCommand dbcmd = dbcon.CreateCommand();
       // requires a table to be created named employee
       // with columns firstname and lastname
       // such as,
       //        CREATE TABLE employee (
       //           firstname varchar(32),
       //           lastname varchar(32));
       string sql =
          &quot;SELECT firstname, lastname &quot; +
          &quot;FROM employee&quot;;
       dbcmd.CommandText = sql;
       IDataReader reader = dbcmd.ExecuteReader();
       while(reader.Read()) {
            string FirstName = reader.GetString (0);
            string LastName = reader.GetString (1);
            Console.WriteLine(&quot;Name: &quot; +
                FirstName + &quot; &quot; + LastName);
       }
       // clean up
       reader.Close();
       reader = null;
       dbcmd.Dispose();
       dbcmd = null;
       dbcon.Close();
       dbcon = null;
    }
}
   
 
如果你想找一個 SQLite 管理工具，我個人推薦使用 SQLiteSpy ，既小又方便而且還免安裝。 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/2926961.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 29 Mar 2007 15:14:09 +0800</pubDate>
					</item>
	<item>
		<title>讀取網頁(4) / Thinking more...</title>
		<description>更快的方法，就是直接利用 .Net 2.0 提供的 WebBrowser 控制項。

不過，如果用這方法，有兩個缺點：  .Net 1.1 不適用，因為 class library 沒提供。  當直接使用 DocumentText 屬性的時候，WebBrowser 沒有轉換編碼，而是直接以 ascii 傳回。  必須是 Windows form 應用程式  

那麼，我們要怎麼自行轉換編碼呢？
首先利用 Reflector 來反組譯一下 DocumentText 屬性，這下就可以很清楚看到他是以 StreamReader 去讀取 DocumentStream。
所以當我們確信網頁的編碼是 UTF-8 時，就可以這麼寫了：
 
    Stream documentStream = webBrowser1.DocumentStream;
    if (documentStream == null)
        return &quot;&quot;;
    StreamReader reader = new StreamReader(documentStream, Encoding.UTF8);
    documentStream.Position = 0;
    string documentText = reader.ReadToEnd();
 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/2922625.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 28 Mar 2007 16:48:16 +0800</pubDate>
					</item>
	<item>
		<title>在 mono 上使用 Font 的一些事 / Thinking more...</title>
		<description>昨天碰到的事情，紀錄一下：
   mono  1.0 類別庫裡的 Font，有一些 ctor 裡面是空的。如果你發現使用了某個 function 沒作用，或是有些問題，你可以參考一下 Mono Class Status 以取得類別庫實作的狀況～或者利用 Reflector for .NET 反組譯看看，免得傻傻在那邊查了半天還不知道原因出在哪。  字型的底層是  libgdiplus ，更底層則是 Cairo 。 Cairo 又再使用了 FreeType 函式庫(好像還有別的，不過這是主要的)。所以字型的設定是取決於fontconfig的設定：/etc/fonts/fonts.conf(用 FreeType 好像跟這設定沒啥關係，總之我是這樣聯想到的)，當你使用某個字型卻無法正常顯示時(例如中文)，不妨參考設定然後直接指定字型名稱： Font textFont = new Font( &quot;AR PL Mingti2L Big5&quot;, 12, FontStyle.Regular, GraphicsUnit.Pixel, 1, false); ，應該就行了。  

</description>
		<link>http://blog.roodo.com/thinkingmore/archives/2856341.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 15 Mar 2007 11:47:37 +0800</pubDate>
					</item>
	<item>
		<title>在.Net如何產生動畫gif (animated gif) / Thinking more...</title>
		<description>原生的 .Net framework 雖然可以產生 gif 圖檔，但卻無法產生有動畫效果的 gif 圖檔。 
找了半天，本來已經萬念俱灰，想說可能要自己來寫了。 
但終於還是在 SourceForge.net 找到合用的library： NGif 。 
 
下載以後，可以直接參考程式，使用方法很簡單～ 
這邊摘錄製作的方法： 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* create Gif */  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //you should replace filepath  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String  [] imageFilePaths =  new   String []{ &amp;quot;G:\\01.png&amp;quot; };  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String  outputFilePath =  &amp;quot;G:\\test.gif&amp;quot; ; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;AnimatedGifEncoder e =  new  AnimatedGifEncoder(); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e.Start( outputFilePath ); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e.SetDelay(500); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //-1:no repeat,0:always repeat  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e.SetRepeat(0); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for  ( int  i = 0, count = imageFilePaths.Length; i &amp;lt; count; i++ )  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e.AddFrame(  Image .FromFile( imageFilePaths[i] ) ); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e.Finish(); 
 
 
 NGif 同時也提供解開的方法，所以你也可以將 gif 裡面的每個 frame 都個別存為獨立的圖檔。 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/2851461.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 14 Mar 2007 15:29:41 +0800</pubDate>
					</item>
	<item>
		<title>讀取網頁(3) / Thinking more...</title>
		<description>WebClient 畢竟還是有一些限制，例如 Cookie，這就沒辦法了，你必須要自行操作 Header。 
可是 WebClient 並沒有任何成員可以讓你實現這塊。 
 
而 WebClient 的底層，其實是用 WebRequest 來實現的。這裡的例子使用了  HttpWebRequest，但其實 HttpWebRequest 也是繼承自 WebRequest。 
要加上 Cookie 的話，你得指定 HttpWebRequest 的 CookieContainer 屬性。 
 
所以我們很快就可以寫出 wgetInWebRequest()。 
 using  System; 
 using  System.Text; 
 using  System.Text.RegularExpressions; 
 using  System.Net; 
 using  System.Web; 
 using  System.IO; 
 using  System.Diagnostics; 
 using  System.Collections; 
 
 public   class  Network 
{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public   static   string  wgetInWebRequest(  string  url,  CookieContainer  cookies,  Encoding  encoding ) 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string  responseData =  &amp;quot;&amp;quot; ; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HttpWebRequest  webRequest = ( HttpWebRequest ) WebRequest .Create( url ); 
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 加上 Cookie  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;webRequest. CookieContainer  = cookies; 
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 如果你有 Proxy 的話～  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // webRequest.Proxy = new WebProxy( &amp;quot;your_proxy&amp;quot;, 3128 );  
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 加上 User Agent，用來模擬瀏覽器～  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //webRequest.Headers.Add( &amp;quot;User-Agent&amp;quot;,&amp;quot;Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)&amp;quot;);  
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; StreamReader  responseReader; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;responseReader =  new   StreamReader (webRequest.GetResponse().GetResponseStream(), encoding ); 
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // and read the response  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;responseData = responseReader.ReadToEnd(); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch (  Exception  ex ) 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Debug .WriteLine( ex.ToString() ); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; finally  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Debug .WriteLine( responseData ); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return  responseData; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
} 
我想，也許你會問這有什麼用？ 
一般網站應用系統登入以後，都會設置 Cookie 以表示你已經登入了，換句話說，你只要先設法模擬登入，然後取得 WebResponse 所得到的 Cookie，接著再把得到的 Cookie 放到 WebRequest.CookieContainer，你接下來所有對該網站應用程式的 Request 就已經是有特定使用者身份的了～ 
讓我舉個 ASP.Net 網站的例子吧～ 

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public   static   void   Login (  string  user,  string  pwd) 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string  loginPage = wgetInWebRequest(  &amp;quot;http://your_web_app/login.aspx&amp;quot; ,  null ,  Encoding .Default ); 
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ASP.Net 會在頁面埋一個 __VIEWSTATE 隱藏表單變數，先取得！  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Regex  rx =  new   Regex (@ &amp;quot;\&amp;lt;input\ type=&amp;quot;  &amp;quot;hidden&amp;quot;  &amp;quot;\ name=&amp;quot;  &amp;quot;__VIEWSTATE&amp;quot;  &amp;quot;\ value=&amp;quot;  &amp;quot;(?&amp;lt;viewstate&amp;gt;.+)&amp;quot;  &amp;quot;\ /\&amp;gt;&amp;quot; ); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string  viewstate =  &amp;quot;&amp;quot; ; 
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try  { 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Find matches.  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MatchCollection  matches = rx.Matches( loginPage ); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( matches.Count == 1 ) 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 要作 UrlEncode  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;viewstate =  HttpUtility .UrlEncode( matches[0].Groups[ &amp;quot;viewstate&amp;quot; ].Value ); 
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 用來收 cookie 的容器  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CookieContainer  cookies =  new   CookieContainer (); 
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // now post to the login form  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HttpWebRequest  webRequest = ( HttpWebRequest ) WebRequest .Create(  &amp;quot;http://your_web_app/login.aspx&amp;quot;  ); 
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 模擬瀏覽器  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //webRequest.Headers.Add( &amp;quot;User-Agent&amp;quot;,&amp;quot;Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)&amp;quot;);  
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // POST  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;webRequest.Method =  &amp;quot;POST&amp;quot; ; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;webRequest. ContentType  =  &amp;quot;application/x-www-form-urlencoded&amp;quot; ; 
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 收到的 cookies 會放到 cookies 變數  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;webRequest. CookieContainer  = cookies; 
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 如果你有 proxy 的話  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // webRequest.Proxy = new WebProxy( &amp;quot;your_proxy&amp;quot;, 3128 );  
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 這邊要看 login 表單有哪些變數而定，請自行變化  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string  postData =  string . Format (  &amp;quot;__VIEWSTATE={0}&amp;user={1}&amp;password={2}&amp;Submit=Submit&amp;quot; , viewstate, user, pwd ); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; StreamWriter  requestWriter =  new   StreamWriter (webRequest.GetRequestStream()); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;requestWriter.Write(postData); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;requestWriter.Close(); 
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 收到內容啦，但是我們不需要他的結果，只要 cookies  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;webRequest.GetResponse().Close(); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // now we can send out cookie along with a request for the protected page  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string  responseData = wgetInWebRequest(  &amp;quot;http://your_web_app/default.aspx&amp;quot; , cookies,  Encoding .Default ); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Debug .WriteLine( responseData ); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Debug .WriteLine(  &amp;quot;Internal error, too many ViewState.&amp;quot;  ); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch (  Exception  ex ) { 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Debug .WriteLine( ex.ToString() ); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; finally  { 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
 
大致上就是這樣子，我不作太多的說明囉～ 
想要作更多的話，可以再研究HTTP Protocal並配合Sniffer之類的軟體去監看網路封包，來了解詳細的流程。 
 </description>
		<link>http://blog.roodo.com/thinkingmore/archives/2830127.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 09 Mar 2007 17:26:07 +0800</pubDate>
					</item>
	<item>
		<title>讀取網頁(2) / Thinking more...</title>
		<description>上一篇最後留下 Encoding 的問題還沒解決，事實上已經有解了：你可以改用 DownloadString() 函數。

DownloadString() 是怎麼做到的呢？
他是先看 WebRequest 得到的 Header 裡面是否有 Content-Type ，如果有指定的話，再看他裡面是否指定 charset，如果有，就以此編碼去讀取 stream。
如果沒有指定的話呢？.Net 2.0 的 WebClient 多提供了 Encoding 屬性，換句話說，就會以 Encoding 屬性指定的編碼去讀取 stream。

事實上，大部分的 browser 並沒這麼笨～他還會先去偷看網頁內容是否有指定 Content-Type 這個 meta tag： &amp;lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&amp;gt; 
如果有的話，就會以此 charset 所指定的編碼來讀取。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/2798103.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Sat, 03 Mar 2007 16:57:56 +0800</pubDate>
					</item>
	<item>
		<title>讀取網頁(1) / Thinking more...</title>
		<description>如果你要搞個 spider 或是 bot，需要讀取網頁的話，用 WebClient 就綽綽有餘了～ 

 using  System.Net; 
 
 public   class  Network 
{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public   static   string  wget(  string  url ) 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WebClient  _client= new   WebClient (); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string  result= &amp;quot;&amp;quot; ; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try  { 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 藉著修改 Header，可以用來模擬某特定 Browser，以下是模擬 IE 6  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_client.Headers.Add( &amp;quot;Accept&amp;quot; , &amp;quot;image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*&amp;quot; ); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_client.Headers.Add( &amp;quot;Accept-Language&amp;quot; , &amp;quot;zh-tw&amp;quot; ); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_client.Headers.Add( &amp;quot;User-Agent&amp;quot; , &amp;quot;Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)&amp;quot; ); 
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 表示支援壓縮，也就是說，你可以丟壓縮過的資料過來，我來解～  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //_client.Headers.Add(&amp;quot;Accept-Encoding&amp;quot;,&amp;quot;gzip, deflate&amp;quot;);  
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // read  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;System.IO. Stream  objStream=_client.OpenRead( url ); 
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 要知道正確的編碼，再去讀取～.Net會幫我們自動轉為 unicode 字串。這邊預設都是 UTF8  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;System.IO. StreamReader  _reader= new  System.IO. StreamReader (objStream,System.Text. Encoding .UTF8); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //System.IO.StreamReader _reader=new System.IO.StreamReader(objStream,System.Text.Encoding.GetEncoding(950));  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result = _reader.ReadToEnd(); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch (  Exception  ex ) { 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw  ex; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; finally  { 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return  result; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
} 
 
所以我們就可以這麼用
 Console .WriteLine( Network.wget( &amp;quot;http://www.google.com.tw&amp;quot; ) ); 
 
目前有個決定性的缺點：必須先知道網頁編碼，我們才能讀到正確的文字～有辦法先知道網頁的編碼，再去決定要怎麼讀取嗎？
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/2782355.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 28 Feb 2007 17:32:34 +0800</pubDate>
					</item>
	<item>
		<title>雞尾酒排序 / Thinking more...</title>
		<description>早上翻譯了 這篇：雞尾酒排序 ，翻譯的不是很好～以後再求改進吧。
順手再寫了 c# 的版本。

 public   static   void  cocktailSort(  int [] theList ) { &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int  bottom = 0; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int  top = theList.Length-1; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; bool  swapped =  true ; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while ( swapped ==  true  ) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;swapped =  false ; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (  int  i=bottom; i&amp;lt;top; i++ ) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( theList[i] &amp;gt; theList[i+1] ) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int  tmp = theList[i+1]; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;theList[i+1]=theList[i]; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;theList[i]=tmp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;swapped =  true ; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;top = top-1; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (  int  i=top; i&amp;gt;bottom; i-- ) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( theList[i]&amp;lt;theList[i-1] ) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int  tmp = theList[i-1]; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;theList[i-1]=theList[i]; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;theList[i]=tmp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;swapped =  true ; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bottom = bottom+1; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} } </description>
		<link>http://blog.roodo.com/thinkingmore/archives/2272852.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 10 Oct 2006 13:37:38 +0800</pubDate>
					</item>
	<item>
		<title>SharpDevelop2 + IronPython + PythonBinding / Thinking more...</title>
		<description>現在你可以用 SharpDevelop2 開發 IronPython 應用程式了。

1.首先下載 PythonBinding ，目前最新的版本是 0.5Beta。
2.解開，這裡我是將解開後的檔案放到 c:\tools\pythonbinding
3.打開 SharpDevelop2
4.[Tools][AddInManager]，選 Install AddIn
5.指向剛剛 c:\tools\pythonbinding\PythonBinding.AddIn，接著按下 Close。
6.關閉 SharpDevleop2，重新啟動。

接下來，你可以 New Solution，就會看到 Python 的部份
   

所以請新增一個 console application，這裡我命名為 hellopython。
這個新的專案裡面已經有個 Program.py 了，他只簡單的印出 &quot;Hello world&quot;。
這時候很直覺的按下綠色的三角形，也就是執行，SharpDevelop2 會很直接的告訴你有問題。
  The &quot;IronPythonCompilerTask&quot; was not given a value for the required parameter &quot;Mainfile&quot;. (MSB4044) 

你需要修改一下專案的屬性：以滑鼠右鍵點選左邊的專案，然後選 Property，依照下圖將 Start Object 修改為 Program.py
   

再次按下執行，SharpDevelop2 很順利地 build 完成，但卻仍然無法執行，SharpDevelop2 會這麼告訴你：
 Exception System.ArgumentException was thrown in debuggee:
The path is not of a legal form.

NormalizePathFast()
GetFullPathInternal()
GetFullPath()
ExecuteCompiled()
Main()
 

可是我以 console 模式去執行編譯出來的 HelloPython.exe，卻可以執行。
後來仔細看了一下工具列，原來按下紅色的驚嘆號就可以順利執行了。
   

我想應該是 SharpDevelop2 還不支援 IronPython 的除錯模式的關係。
此外，目前也還不支援 Auto completion(自動完成)，我想這部份應該很快就會被 release 出來了吧。

參考資料：   I cannot build the starter console project Posts   
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/2163653.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 18 Sep 2006 18:58:43 +0800</pubDate>
					</item>
	<item>
		<title>IronPython(4) - 類別、繼承、模組化 / Thinking more...</title>
		<description>基本上還是跟上次的一樣，只是我們要重新寫過，直接繼承 Form 類別，然後模組化。

Python 定義類別的方法相當簡單：
 class classname( parentclass ):
&amp;nbsp;&amp;nbsp;def __init__( self ):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# initialize
&amp;nbsp;&amp;nbsp;def doSomething( self ):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# do something
 
他是以左邊的縮排來決定範圍，所以同樣縮排就表示是同一區塊。
self 則是表示自己，也就類似 c# 的 this。

所以我們把昨天的程式碼重新寫過：
 import clr
clr.AddReferenceByPartialName(&quot;System.Windows.Forms&quot;)
clr.AddReferenceByPartialName(&quot;System.Drawing&quot;)
from System.Windows.Forms import *
from System.Drawing import *

class OptionForm( Form ):
&amp;nbsp;&amp;nbsp;def __init__(self):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.InitializeComponent()

&amp;nbsp;&amp;nbsp;def InitializeComponent(self):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.Text = &quot;RSSMSN - customize your msn personal message&quot;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# Initialize Label
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lblHello = Label(Text=&quot;Hello world!&quot; )
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lblHello.Visible=True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lblHello.Location=Point( 10, 10 )
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lblHello.AutoSize=True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.Controls.Add( lblHello )

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# Initialize NotifyIcon
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;notifyIcon1 = NotifyIcon( Visible=True, Text=&quot;RSSMSN&quot;, Icon=Icon(&quot;Matrix.ico&quot;) )

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# Initialize Form
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.StartPosition=FormStartPosition.CenterScreen
 
大致上就會是這樣子，我們將這個檔案命名為 fmOption.py。

主程式則另外放到 main.py：
 import clr
clr.AddReferenceByPartialName(&quot;System.Windows.Forms&quot;)
clr.AddReferenceByPartialName(&quot;System.Drawing&quot;)
from System.Windows.Forms import *
from System.Drawing import *
from fmOption import * 

f = OptionForm()
Application.Run(f)
 
你可以看到主程式變得簡單許多。這邊只需要將剛剛寫好的 fmOption.py 引用進來，再將 OptionForm 實體化，請 Application 類別去把窗開出來就好了。
Python 引用其他檔案的方法，統一都是 from your_module import classname。
這個 your_module 可以是 assembly name 也可以是 module name。

大致上就是這樣子了。

下次的目標是加上 destructor 以確保 System Tray 的 Icon 會在程式結束時消失。

參考資料：   5.2. Importing Modules Using from module import    5.3. Defining Classes    5.4. Instantiating Classes   
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/1847394.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 04 Jul 2006 12:36:00 +0800</pubDate>
					</item>
	<item>
		<title>IronPython(3) - 第一個窗 / Thinking more...</title>
		<description>基本上參考 tutorial/wfdemo.py 就可以很快的寫出來第一個窗。

 import clr
clr.AddReferenceByPartialName(&quot;System.Windows.Forms&quot;)
clr.AddReferenceByPartialName(&quot;System.Drawing&quot;)
from System.Windows.Forms import *
from System.Drawing import *

f = Form()
f.Text = &quot;RSSMSN - customize your msn personal message&quot;

# Initialize Label
lblHello = Label(Text=&quot;Hello world!&quot; )
lblHello.Visible=True
lblHello.Location=Point( 10, 10 )
lblHello.AutoSize=True
f.Controls.Add( lblHello )

# Initialize NotifyIcon
notifyIcon1 = NotifyIcon( Visible=True, Text=&quot;RSSMSN&quot;, Icon=Icon(&quot;Matrix.ico&quot;) )

# Initialize Form
f.StartPosition=FormStartPosition.CenterScreen

Application.Run(f)
 

他是直接產生 Form 與 Label 的實體，然後丟給 Application，就可以很順利的產生第一個窗。
這裡有個有趣的用法：
 lblHello = Label( Text=&quot;Hello world!&quot; ) 
所以產生實體的時候，可以直接以 PropertyName=value 來指定 Property 的初始值。

但是這樣的寫法，在後期大概會寫到暈倒。
所以還是要搞清楚如何撰寫類別並且繼承才會是比較好的解法。

下次的目標：撰寫類別與繼承。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/1842752.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 03 Jul 2006 12:32:13 +0800</pubDate>
					</item>
	<item>
		<title>IronPython(2) - 使用 rsstoolkit / Thinking more...</title>
		<description>
世界上總是有許多人願意提供他們的心血，我們只需要站在他們的肩膀上，就可以快速的發展出我們自己的東西來。
 ASP.NET RSS Toolkit  是一個存取 RSS 的 library，其他相關的 Library 還有  RSS.Net ，但是目前 RSS.Net 還沒有釋出 for .Net 2.0 的版本，所以我們選用  ASP.NET RSS Toolkit 。

首先下載並解開作者所提供的壓縮檔案，將 bin 目錄下的 RssToolKit.dll 複製到 IronPython 目錄下的 lib，以方便 IronPython 取用。
執行 IronPython，要在 IronPython 使用別人寫好的 library(Assembly)，有兩個步驟，首先要載入 library，然後再 import 裡面的類別。
 import clr
clr.AddReferenceToFile(&quot;RssToolkit.dll&quot;)
from RssToolkit import *
 

話說回來  ASP.NET RSS Toolkit 的說明文件真的是可以用 Poor 來形容，裡面附的一份 Word 文件，就僅描述如何在 Visual Studio 2005 下使用而已，完全沒提及 ASP.NET RSS Toolkit 裡面有什麼類別，類別又有什麼屬性... Orz...
還好 ASP.NET RSS Toolkit 有附原始碼，Trace 一下就能瞭解一二。

所以接下來先 initialize 變數。
 Python 處理變數也蠻像 BASIC 的，隨寫即用：
 r = RssDataSource() 
連 new 都不用寫。

RSS 的構造主要是以 Channel 為主，所以 r.Channel 就表示 Channel，r.Channel.Items 就表示 Channel 裡面的各個項目。
有了這些資訊，就可以寫出取 RSS 資訊的程式了。
可是 Python 的迴圈該怎麼寫呢？因為我們要取出 Items 裡的每個項目。
for...next 的寫法
 for i in range(5):
	print i
 

foreach 的寫法
 
for item in r.Channel.Items:
	print item[&quot;title&quot;]
 

總結這些，我們就可以寫出一個取出 RSS 內各項目的程式了：
 
import clr
clr.AddReferenceToFile( &quot;RssToolkit.dll&quot; )
from RssToolkit import *

r = RssDataSource()
r.Url = &quot;http://tw.news.yahoo.com/rss/realtime&quot;

print r.Channel[&quot;title&quot;]

for item in r.Channel.Items:
	print item[&quot;title&quot;]
	print item[&quot;link&quot;]
 

下次的目標，一個簡單的視窗 + 縮小到 System tray。

參考資料：
   6.3. Iterating with for Loops    Awesome ASP.NET 2.0 RSS Tool-Kit Released   
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/1832850.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 30 Jun 2006 12:41:55 +0800</pubDate>
					</item>
	<item>
		<title>NAnt(3) - 各個擊破 / Thinking more...</title>
		<description>一個 solution (方案)裡面可能不只一個 project，可能會有許多個。
以前，我會寫在同一個 build 檔案裡面，可是這樣會讓 build 變得很大而且難以維護。
 NAnt 可以讓你在 build 檔案裡面再去呼叫另外一個 build 檔案，如此一來，我們就可以讓各 build 檔案負責自己的事情，避免都放到同一個 build 檔案裡面了。

語法很簡單，利用 nant 這個 task 就可以達成：
 &amp;lt;nant&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;lt;buildfiles&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;include name=&amp;quot;subdir/default.build&amp;quot; /&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;lt;/buildfiles&amp;gt;
&amp;lt;/nant&amp;gt;
 

或者是偷懶一點，讓 NAnt 找到目前所在目錄下所有子目錄下的 build 檔案，然後進行 build
 &amp;lt;nant&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;lt;buildfiles&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;include name=&amp;quot;**/default.build&amp;quot; /&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;lt;/buildfiles&amp;gt;
&amp;lt;/nant&amp;gt;
 

如果，要執行的並不是 build 這個預設 target 的話，該怎麼辦呢？
你可以為 nant task 加上 target 這個 attribute，就行了。
 &amp;lt;nant target=&quot;clean&quot;&amp;gt;....&amp;lt;/nant&amp;gt; 

最後，我們達到各個擊破的目的。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/1829162.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 29 Jun 2006 12:27:47 +0800</pubDate>
					</item>
	<item>
		<title>IronPython(1) - 安裝與執行 script / Thinking more...</title>
		<description>IronPython 是一個移植到 .Net framework 之上的 Python 分支，與其他 Python 最大的不同點就是他可以直接調用 .Net framework 內的所有類別庫。

安裝前的必要條件：
   Microsoft .NET Framework Version 2.0 Redistributable Package (x86) 。  

官方既下載網址：
   IronPython   

目前最新的版本是 Beta 8，下載以後的安裝非常簡單，解開以後就可以了。
點選 IronPythonConsole.exe 就可以執行。

還記得以前的 BASIC 嗎？(我想大概很少人知道這種古早又親切的語言了)
你可以試著輸入 print &quot;Hello world!&quot; 
或是 print 1+2 
就可以快速看到你指令的輸出結果。

接著我們試試看執行官方提供的範例： execfile( &quot;tutorial/wfdemo.py&quot; ) 
畫面會帶出一個視窗，你可以試試看在上面以滑鼠隨意點選一點，視窗會出現 &quot;Hello&quot; 的字樣。
讓我們將視窗關閉，按下 ctrl+z 離開 PythonConsole。

學習需要目標，我想試著用 IronPython 重寫  RSSMSN 。
甚至以後再用 Python + PyGTK(或 wxWidget) 來重寫看看。

明天的目標，讀取 RSS。

其他可以參考的資料：  Tutorial 目錄下的 tutorial.htm   Dive Into Python    Python 研究(Dive Into Python)    Python Tutorial    你今天Python了吗？（上）    wx.NET - ImageViewer Tutorial   
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/1829126.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 29 Jun 2006 12:23:26 +0800</pubDate>
					</item>
	<item>
		<title>錯誤 1935 / Thinking more...</title>
		<description>在某些時候，安裝 .Net framework redistributable package 會失敗，出現如下的錯誤訊息：
錯誤 1935。An error occured during the installation of assembly component {....}. HRESULT: -2147319761.

   

這時候你可以參考這位大老寫的剖析，相當清楚： Troubleshooting 1935 and 2908 errors during installation 

我(或者應該說是我朋友)遇到的情況是用如下步驟就可解決：
  將 %windir%\system32\mscoree.dll (在 Windows 98/me 上是 %windir%\system\mscoree.dll) 更名。  如果 %windir%\system32\urttemp 存在的話，刪除掉。(在 Windows 98/me 上是 %windir%\system\urttemp)  重新執行 .Net framework redistributable package 安裝程式  
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/1732101.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 09 Jun 2006 16:36:52 +0800</pubDate>
					</item>
	<item>
		<title>Porting / Thinking more...</title>
		<description>也許移植一個 .Net application 到其他平台上，並不如想像中容易。
正如 Java application 並不是 100% 的 run anywhere。

 Mono 專案的頭頭最近把 Paint.NET 移植到 Linux 的 Mono 上，你可以看看這篇他的文章： Porting Paint.NET to Mono 。

看到這個標題，我是很高興的，可是看完以後，發現移植的過程曲折離奇，其中的過程頗值得玩味。


</description>
		<link>http://blog.roodo.com/thinkingmore/archives/1639923.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Sat, 20 May 2006 21:39:32 +0800</pubDate>
					</item>
	<item>
		<title>資料繫結與巡覽 / Thinking more...</title>
		<description>資料的繫結基本上都是靠 Controls.DataBindings，所以
 text1.DataBindings.Add( new Binding(&quot;Text&quot;, ds, &quot;customers.custNo&quot;) ); 
就可以把 text1 這個控制項的 Text 屬性繫結到 ds.Tables[&quot;customers&quot;] 的 custNo 欄位上。

如果想要有一些處理與變化，那麼可以透過 Binding.Format 與 Binding.Parse：
 Binding b=new Binding(&quot;Text&quot;, ds, &quot;customers.custOrder.OrderAmount&quot;);
b.Parse+=new ConvertEventHandler( currencyStringToDecimal); // currencyStringToDecimal 是自訂的
b.Format+=new ConvertEventHandler( DecimalToCurrencyString ); // DecimalToCurrencyString 也是...
text3.DataBindings.Add(b);
 
這表示在轉換控制項屬性到資料來源的時候，會透過這兩個事件作變化。
Parse 表示控制項到資料來源，而 Format 正好相反。

都繫結上了以後呢？我們可以透過 BindingManagerBase 來作巡覽。
 BinderManagerBase bm = BindingContext[ dataset, &quot;tablename&quot; ]; 
此時可用 bm.Position 取得位置，bm.Current 取得當前的物件(如果資料來源是 datatable，那就是 DataRowView；若是陣列，那就是所指向的元素)
bm.Position+1 就是下一筆，反之則是上一筆。到了最後一筆的時候，bm.Position+1 以後仍然會是一樣。

那麼，位置移動的時候會觸發甚麼事件？PositionChanged。所以我們可以撰寫自己的處理事件，
 PositionChanged+=new EventHandler( this.fmMain_PositionChanged ) 

不僅僅是 TextBox 可以作，只要有提供 DataBindings 屬性的控制項都可以。
把 Button 的 Text 屬性 Bind 到某資料來源的某欄，而 Enable 屬性又 Bind 到 某欄時，那麼當移動資料來源位置的時候，就可以讓 Button 的相關狀態自動改變了。
這讓我想到似乎可以作一些 state machine 的東西...

</description>
		<link>http://blog.roodo.com/thinkingmore/archives/1488957.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 28 Apr 2006 14:24:07 +0800</pubDate>
					</item>
	<item>
		<title>IDeserializationCallback.OnDeserialization() / Thinking more...</title>
		<description>在 deserialization 之後，需要做的一些處理可以寫在這裡。
.Net framework documentation 裡面的例子是以 Circle 類別作例子，圓的面積不 serialize，而是在 deserialize 之後再計算出來。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/1471287.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 25 Apr 2006 16:54:35 +0800</pubDate>
					</item>
	<item>
		<title>NAnt (2) / Thinking more...</title>
		<description>看完上一篇，你大概會想，要寫的 task 是如此之少，這真是太完美了。
但是對於笨Q來說，不幸的事情發生了...

笨Q 聽說 .Net 也移植到 Linux 上了，所以他想試試看把上篇的程式拿到 Linux 下編譯，於是笨 Q 安裝了 Mono。接著安裝 NAnt。

同樣他下載了 NAnt, 並且解開，放到 /opt/nant 下。
再把整個專案複製到 Linux 下，並且修改了一下 build 檔的內容，由
 &amp;lt;property name=&quot;nant.settings.currentframework&quot; value=&quot;net-1.1&quot;/&amp;gt; 
改為
 &amp;lt;property name=&quot;nant.settings.currentframework&quot; value=&quot;mono-1.0&quot;/&amp;gt; 
讓 NAnt 在建立專案前自動把編譯環境切換為 mono。

接著輸入
$mono /opt/nant/bin/NAnt.exe

這時只見 NAnt 很不爭氣的吐了一句：
 Invalid element &amp;lt;solution&amp;gt;. Unknown task or datatype 

笨Q 只能流淚默默接受這個事實，他知道必須自己學著寫 target。

 

一個 NAnt 的 build 檔案其實是一個 XML 檔案，最基本的元素是 project，project 則是由 target 與 property 組成的，而 target 則是由許多的 task 組成的。
所以一個空的 build 檔案是長這個樣子：
    ?xml  version=  &amp;quot;1.0&amp;quot; ?&amp;gt;     &amp;lt;project  name=  &amp;quot;dnsedu&amp;quot;  default=  &quot;build&quot;&gt;               &amp;nbsp;&amp;nbsp;&amp;lt;property  name= &quot;nant.settings.currentframework&quot;  value= &quot;net-1.1&quot;/  &amp;gt;   &amp;nbsp;&amp;nbsp;&amp;lt;target  name= &quot;build&quot; description= &amp;quot;Default build target&amp;quot;  depends= &amp;quot;dnsedu&amp;quot; &amp;gt;   &amp;nbsp;&amp;nbsp;&amp;lt;  /target&amp;gt;     &amp;lt;  /project&gt;

那麼 target 裡面有哪些 task 可以用呢？你可以參考官方網站的 這裡 。
裡面真的很多 task，除了基本編譯(csc, vbc, cl, al, ilasm, resgen)之外，他還有 copy, cvs, mail, nunit ...等等的 task，絕對可以讓你組合出你想要的東西。

要改寫上篇的 build(我假設你用 c#)，我們會用到 csc、mkdir 這兩個主要的 task。

以下是改寫好的 build 檔案
&amp;lt;project name=&amp;quot;your_project&amp;quot; default=&amp;quot;build&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;nant.settings.currentframework&amp;quot; value=&amp;quot;mono-1.0&amp;quot;/&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;debug&amp;quot; value=&amp;quot;false&amp;quot;/&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;lt;target name=&amp;quot;build&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;mkdir dir=&amp;quot;bin&amp;quot; unless=&amp;quot;${directory::exists(&#039;bin&#039;)}&amp;quot; /&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;csc target=&amp;quot;winexe&amp;quot; output=&amp;quot;bin/your_project.exe&amp;quot; debug=&amp;quot;${debug}&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;sources&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;include name=&amp;quot;*.cs&amp;quot;/&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/sources&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;references&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;include name=&amp;quot;System.Drawing.dll&amp;quot; /&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;include name=&amp;quot;System.Data.dll&amp;quot; /&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;include name=&amp;quot;System.Windows.Forms.dll&amp;quot;/&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/references&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;resources&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;include name=&amp;quot;*.resx&amp;quot;/&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/resources&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/csc&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;lt;/target&amp;gt;
&amp;lt;/project&amp;gt;

mkdir task 這邊我使用了 unless，意思是 if not，所以意思就是當目錄不存在的時候，就建立一個。這裡判斷目錄是否存在的函數是 NAnt 內建的，想知道有哪些函數可用，可以參考NAnt官方網站的 這邊 。

csc task 裡面，則需要指定輸出類型(target)，輸出檔名(output)以及要不要包含除錯資訊(debug)。
夾在 &amp;lt;csc&amp;gt;&amp;lt;/csc&amp;gt; 裡面的，就是指定你 c# 程式，所引用(或參考)到的組件以及所使用的資源檔。
很簡單，對吧～

這就是最基本的囉，下次我們來談談 web 應用程式的部份。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/1451235.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 21 Apr 2006 17:33:10 +0800</pubDate>
					</item>
	<item>
		<title>NAnt (1) / Thinking more...</title>
		<description>在 .Net 2.0 以前，如果不使用 IDE 來建立專案，而想要直接在命令列打個指令就可以建立的話，你有 3 種選擇：  批次檔  Makefile   NAnt   
.Net 2.0 之後，多了一種選擇：msbuild。

這一系列文章主要是討論 NAnt，可是為甚麼要用 NAnt ? 又為甚麼要用 NAnt ??
簡單來說，爽。

如果要講跨平台，用 Makefile、msbuild (mono 已經搞了一個工具叫 xbuild，與 msbuild 相容) 都可以跨平台。
如果要講簡單，我個人是覺得 Makefile 比他還簡單。
如果要講功能，msbuild 也不遑多讓。
所以我說，就是一個爽。

Ant 是 Java 平台上一個極為重要的工具，而NAnt 最早是想把 Ant 移植到 .Net 上，所以才叫做 NAnt。
官方網址在： http://nant.sourceforge.net 
下載 .zip 檔案以後，解開就可以用了，沒什麼特別的安裝步驟，即便是 Linux 也一樣。
我假設你解開以後會放到 c:\tools 下，並更名為 nant 。

廢話不多說了，直接從第一個實例開始。
我想一般人還是很習慣用 Visual Studio.Net 來開發吧。

所以，先隨便建立一個 Windows form 專案，確定它可以編譯。(或者你也可以用你手頭上的專案來試試)
接著在該專案目錄下，建立一個文字檔，並命名為 your_project.build (是了，your_project 你得自己替換一下。)
裡面放置如下內容：
 &amp;lt;?xml version=&quot;1.0&quot;?&amp;gt;
&amp;lt;project name=&quot;your_project&quot; default=&quot;build&quot;&amp;gt;
	&amp;lt;property name=&quot;nant.settings.currentframework&quot; value=&quot;net-1.1&quot;/&amp;gt;
	&amp;lt;target name=&quot;build&quot;&amp;gt;
		&amp;lt;solution configuration=&quot;release&quot; solutionfile=&quot;your_project.sln&quot; /&amp;gt;
	&amp;lt;/target&amp;gt;
&amp;lt;/project&amp;gt;
 

存檔以後，進入命令列模式，輸入
 c:\tools\nant\bin\nant 

這樣就大功告成了。
為甚麼可以這麼簡單？因為 NAnt 在 0.85.2296 以後已經添加了解析 Visual Studio 專案檔的能力，所以 build 檔裡面就只要用 solution 這個 task 就可以搞定了。
但是很可惜的是還不支援 Visual Studio 2005，即便是最新的版本也還沒看到蹤跡。
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/1444526.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 20 Apr 2006 14:52:11 +0800</pubDate>
					</item>
	<item>
		<title>Some mono news / Thinking more...</title>
		<description>
 MonoDevelop  Releaes 0.10 版啦~
這次提供了 GUI designer 了喔,也可以作 Refactoring ~~
另外還有我小小的貢獻：zh_TW 的翻譯 :-p
詳情可以看  Release notes for MonoDevelop 0.10 .

看了 Tracking Performance in Mono 才知道，原來已經有個大學從 2004 年開始就在進行追蹤 Mono 效能，並且提供了詳細的報告呢。
報告的網址： Regression Tests - MONO Regression Benchmarking 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/1372364.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 06 Apr 2006 09:25:12 +0800</pubDate>
					</item>
	<item>
		<title>TheServerside.Net 訪談 Miguel De Icaza / Thinking more...</title>
		<description> Q and A with Miguel &amp;quot;Mono Man&amp;quot; De Icaza  
這是一篇訪談,對象是 Mono 專案的 leader,裡面提到很多關於  Mono  的現況與未來發展.

稍微整理一下我看到的:  1.2 beta 1 將會在四月釋出,最主要要完成的是 Windows form 1.1 的部份.  vb.net compiler, 實做狀況不佳,因為 Linuxer 都對 c# 比較可接受,但是你可以先在 windows 編譯好 il (assembly)再拿到 mono 上用.  有討論到關於 object pascal / iron python / ruby 的一些事情.  對 .Net 2.0 的支援, c# 2.0 compiler 都已經完備了, 目前少的是 2.0 的類別庫. 在1.2之後,他們會排定開發順序.  
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/1358697.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 03 Apr 2006 12:20:20 +0800</pubDate>
					</item>
	<item>
		<title>Regular expression in common use / Thinking more...</title>
		<description>剛好要用到,所以特別在網路上找,主要都是給 RegularExpressionValidator 作 validate 用的...
  檢查日期  dd/mm/yyyy  ((([0][1-9]|[12][\d])|[3][01])[-/]([0][13578]|[1][02])[-/][1-9]\d\d\d)|((([0][1-9]|[12][\d])|[3][0])[-/]([0][13456789]|[1][012])[-/][1-9]\d\d\d)|(([0][1-9]|[12][\d])[-/][0][2][-/][1-9]\d([02468][048]|[13579][26]))|(([0][1-9]|[12][0-8])[-/][0][2][-/][1-9]\d\d\d)  yyyy/mm/dd ([1-9]\d\d\d[-/]([0][13578]|[1][02])[-/](([0][1-9]|[12][\d])|[3][01]))|([1-9]\d\d\d)[-/]([0][13456789]|[1][012])[-/](([0][1-9]|[12][\d])|[3][0])|([1-9]\d([02468][048]|[13579][26])[-/][0][2][-/]([0][1-9]|[12][\d]))|([1-9]\d\d\d[-/][0][2][-/]([0][1-9]|[12][0-8]))    限制位數的數字 (^-?\d{1,10}\.$)|(^-?\d{1,10}$)|(^-?\d{0,10}\.\d{1,9}$)  一般數字 ^(-)?\d+(\.\d\d)?$  檢查 e-mail ^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$  查 url ^(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\&#039;\/\\\+&amp;%\$#_]*)?$  

參考資料:   VB.NET - use regular expression validator    How to use Regular Expressions in .NET    How To: Use Regular Expressions to Constrain Input in ASP.NET (PAG Documentation)   
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/1269505.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 17 Mar 2006 09:06:26 +0800</pubDate>
					</item>
	<item>
		<title>ANTLR 與 c# / Thinking more...</title>
		<description>
 ANTLR 是一個用來將剖析語法轉換成語言的工具,如果你接觸過 lex/yacc 的話,就可以很容易瞭解.

這裡有一篇相當簡單的 Introduction .
Step by step, 就可以做出一個計算運算式的小程式.

可是,產生出來的程式語言卻是 java, 如果要改用 c# 呢??
依照官方的說明,  ANTLR  可以產出三種語言: C++, Java, c#.
所以該怎麼產生呢??需不需要另外寫甚麼??
官方網站同樣也提供了這麼一篇: Notes for using the ANTLR C# Code Generator .

這裡我們以 Introduction 裡面所提供的範例來作為例子,將他命名為 &quot;expr.g.txt&quot;:
 class ExprParser extends Parser;

expr returns [int value=0]
{int x;}
    :   value=mexpr
        ( PLUS x=mexpr  {value += x;}
        | MINUS x=mexpr {value -= x;} 
        )*
    ;

mexpr returns [int value=0]
{int x;}
    :   value=atom ( STAR x=atom {value *= x;} )*
    ;

atom returns [int value=0]
    :   i:INT {value=Integer.parseInt(i.getText());}
    |   LPAREN value=expr RPAREN
    ;

class ExprLexer extends Lexer;

options {
    k=2; // needed for newline junk
    charVocabulary=&#039;\u0000&#039;..&#039;\u007F&#039;; // allow ascii
}

LPAREN: &#039;(&#039; ;
RPAREN: &#039;)&#039; ;
PLUS  : &#039;+&#039; ;
MINUS : &#039;-&#039; ;
STAR  : &#039;*&#039; ;
INT   : (&#039;0&#039;..&#039;9&#039;)+ ;
WS    : ( &#039; &#039;
        | &#039;\r&#039; &#039;\n&#039;
        | &#039;\n&#039;
        | &#039;\t&#039;
        )
        {$setType(Token.SKIP);}
      ;    
 

第一步你需要做的,就是在這份例子的最上頭加上
 options {
    language  = &quot;CSharp&quot;;
    namespace = &quot;SmallCalc&quot;;          // encapsulate code in this namespace
    //classHeaderPrefix = &quot;protected&quot;; // use to specify access level for generated class
}
 
表明我們要使用 c#, 並且 namespace 要命名為 SmallCalc.

接著使用下載到的 antlr, 來進行轉換
&amp;gt;antlr expr.g.txt

他會產出下列檔案:
  ExprLexer.cs  ExprParser.cs  ExprParserTokenTypes.cs  ExprParserTokenTypes.txt  

ok, 該有的都有啦,我們接下來需要的是主程式與必要的 antlr assembly(組件).

要取得 antlr assembly, 你必須先取得  antlr 的原始碼  (找 source distribution).
解開原始碼以後,在 lib/csharp/ 下,會有個 visual studio project 檔與 NAnt build 檔.
看你熟悉哪一個,就用哪一個.
總之你會得到 antlr.runtime.dll, 將他複製到剛剛程式所在的位置.

主程式的話,很簡單,就是使用剛剛產生出來的程式來進行剖析:
 using System;
using System.IO;
using antlr;

namespace SmallCalc
{
	public class Smallcalc {
        	public static void Main(String[] args) 
		{
        	    ExprLexer lexer = new ExprLexer( Console.OpenStandardInput() );
	            ExprParser parser = new ExprParser(lexer);
	            int x = parser.expr();
	            Console.WriteLine(x);
	        }
	}
}
 

然後編譯
&amp;gt;C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\csc /target:exe /out:smallcalc.exe /r:system.dll /r:antlr.runtime.dll *.cs

你會發現有點小錯誤:
 ExprParser.cs(156,11): error CS0246: 找不到型別或命名空間名稱 &#039;Integer&#039; (您是否遺漏 using 指示詞或組件參考?) 
稍微調整一下,從原來的 value=Integer.parseInt(i.getText()); 
修正為
 value=Convert.ToInt32( i.getText() ); 

再重新編譯一次,就大功告成了.

試試看結果囉...
 &amp;gt;smallcalc
1+3+5+7*100

709
 

:)

參考資料:
   ANTLR Parser Generator     An Introduction To ANTLR ,這是以簡單的運算式為例.    Notes for using the ANTLR C# Code Generator ,如何產生 c# code, 並且編譯.以及一些選項說明.   
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/1165473.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 24 Feb 2006 10:06:20 +0800</pubDate>
					</item>
	<item>
		<title>樂透下期號碼預測(2) / Thinking more...</title>
		<description>樂透下期號碼預測(2)

今天繼續往下面想以後,發現我以前的想法錯誤了.
本想說,根據歷史資料去統計,以出現次數較少的數字取亂數,又,理論上每個數字出現的次數會趨近一致,所以應該會有較高的機率得到下期中獎的號碼.
回頭想想每期中獎號碼組合機率,應該是以 1 去除以 42 取 6 的所有組合數.

我以排列組合去 Google 找了很多 資料 :   組合    排列與組合    排列组合    排列组合    組合數學   

要怎麼求組合數呢??我們將樂透的規則套入組合公式:
從 42 個數字中,取 6 個號碼,不論順序,組成一組,不同的組合數為: 排列數/42!

排列組的計算: 42 * (42-1) * (42-2) * (42-3) * (42-4) * (42-5)
42!: 42*41*40*....*2*1

所以寫好以後的程式就是這樣:
 using  System;  using  System.Collections;   public   class  MyClass { &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public   static   double  calcP(  double  totalNumbers,  double  pickNumbers ) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; double  possible = 1.0; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (  int  i=0; i&amp;lt;pickNumbers; i++ ) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;possible = possible * (totalNumbers-i); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return  possible; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public   static   double  calcC(  double  totalNumbers,  double  pickNumbers ) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; double  mShock = 1.0;  // m!  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (  long  i=0; i&amp;lt;pickNumbers; i++ ) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mShock = mShock * (i+1); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; double  p = calcP( totalNumbers, pickNumbers ); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ( p/mShock ); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public   static   void  Main() &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console .WriteLine(  &amp;quot;組合數是: {0}&amp;quot; , calcC( 42.0, 6.0 ) ); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RL(); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region Helper methods   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private   static   void  RL() &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console .ReadLine();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion  }

最後算出來的結果是: 5,245,786
也就是說,如果有 5,245,786 人去買的話,至少會有一人中獎.
不過,還是覺得怪怪的...這數字會不會太小了呢??
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/1072850.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 01 Feb 2006 23:42:51 +0800</pubDate>
					</item>
	<item>
		<title>樂透下期號碼預測(1) / Thinking more...</title>
		<description>之前騎車的時候想到的一個 idea,想要來預測下期樂透的號碼.

以亂數取某數字,理論上,當次數越趨近於無限的時候,每個數字出現的機率會趨近於相等.
所以我們寫了這麼一個程式來驗證其正確性:

 using  System;  using  System.Collections;   public   class  MyClass { &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public   static   void  Main() &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Random  r =  new   Random (); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int [] statistics =  new   int [43]; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int  i=0; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int  sum=0; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // initialize  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for ( i=0; i&amp;lt;statistics.Length; i++ ) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;statistics[i]=0; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for ( i=0; i&amp;lt;100000; i++ ) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // int  index =  Convert .ToInt32( 41*r.NextDouble()+1 ); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int index = r.Next(42)+1;  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;statistics[ index ] = statistics[ index ] + 1; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for ( i=0; i&amp;lt;statistics.Length; i++ ) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console .WriteLine(  &amp;quot;statistics[{0}] = {1}&amp;quot; , i, statistics[i] ); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sum+=statistics[i]; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console .WriteLine(  &amp;quot;sum={0}&amp;quot; , sum ); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RL(); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region Helper methods  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private   static   void  RL() &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console .ReadLine();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion  }

這邊遇到一件很有趣的事情,如果你用 41*r.NextDouble()+1 來取的話
結果會是最前面數字與最後面數字出現的機率會比其他數字要少了約一倍.
所以這樣取會比較好些: r.Next(42)+1

另外我們捨棄 [0] 不用,純使用 [1] ~ [42], 以方便我們的統計.

參考資料:   A Lottery Program in C#    Generating Random Number and String in C#    Random Numbers in C#    亂猜是猜中了，還是沒猜中？   

...待續...

</description>
		<link>http://blog.roodo.com/thinkingmore/archives/1069291.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 31 Jan 2006 23:02:53 +0800</pubDate>
					</item>
	<item>
		<title>CheckSum / Thinking more...</title>
		<description>CheckSum 是一個很簡單的檢查方法,把內容拆解成一堆 byte (或word,dword), 如果把這些 bytes 相加起來得到的值一致,表示內容&quot;應該&quot;是沒問題. 
 
 using  System; 
 using  System.IO; 
 using  System.Collections; 
 
 public   class  CheckSum 
{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private   long  sum=0; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public  CheckSum() 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public   void  Add(  int  i ) 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sum += i; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public   void  Add(  byte  b ) 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sum += b; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public   long  GetCheckSum() 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return  sum; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
} 
 
 public   class  MyClass 
{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public   static   void  Main() 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string  filename; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FileStream  fs= null ; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CheckSum sum =  new  CheckSum(); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //Open the stream and read it back.  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console .Write(  &amp;quot;Please input filename:&amp;quot;  ); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;filename =  Console .ReadLine(); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console .WriteLine(  &amp;quot;Trying to read {0}&amp;quot; , filename ); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (  File .Exists( filename ) ) 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console .WriteLine(  &amp;quot;{0} is existed.&amp;quot; , filename ); 
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fs =  File .Open( filename,  FileMode .Open,  FileAccess .Read ); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( fs.CanRead ) 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int  value=0; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while ( (value = fs.ReadByte()) &amp;gt;= 0)  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sum.Add( value ); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console .WriteLine(  &amp;quot;Checksum = {0,8:x}&amp;quot; , sum.GetCheckSum() ); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console .WriteLine(  &amp;quot;Cannot be read&amp;quot;  ); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch (  Exception  ex ) 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console .WriteLine( ex. Message  ); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; finally  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fs.Close(); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RL(); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region Helper methods  
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private   static   void  RL() 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console .ReadLine();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion  
}  
 
 參考資料:   CheckSum on wikipedia    A Checksum Algorithm    </description>
		<link>http://blog.roodo.com/thinkingmore/archives/1046683.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 25 Jan 2006 12:37:28 +0800</pubDate>
					</item>
	<item>
		<title>最大公因數/輾轉相除法 / Thinking more...</title>
		<description>在某論壇看到討論最大公因數的討論串,裡面有提到輾轉相除法.
老實說,當我看到最大公因數,我只想到暴力法.
從 1...n 開始 iterate, 能整除,表示是因數,把這些數字記起來,於是我們得到兩個集合.這兩個集合的交集,表示是共通因數,最大者則為最大公因數.

完全忘記有輾轉相除法這玩意兒,一時興起,port 到 c# 試試看.

 using  System;  using  System.Collections;   public   class  MyClass { &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public   static   int  GCD(  int  a,  int  b ) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( a % b == 0 ) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return  b; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return  GCD( b, a%b ); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public   static   void  Main() &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int  num1=1230, num2=460, num3=10; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int  result1 = GCD( num1, num2 ); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int  result2 = GCD( result1, num3 ); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console .WriteLine(  &amp;quot;The GCD of {0} and {1} is {2}&amp;quot; , num1, num2, result1 ); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console .WriteLine(  &amp;quot;The GCD of {0} and {1} is {2}&amp;quot; , result1, num3, result2 ); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RL(); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region Helper methods  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private   static   void  RL() &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console .ReadLine();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion  }</description>
		<link>http://blog.roodo.com/thinkingmore/archives/1018879.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 18 Jan 2006 17:12:11 +0800</pubDate>
					</item>
	<item>
		<title>Asp.Net 與 tortoisesvn / Thinking more...</title>
		<description>早上去看 tortoisesvn 的時候,發現已經釋出新版,看了一下 新版的發行公告 ,發現新版的tortoisesvn已經解決討厭的 asp.net 問題了.
 The &quot;_svn&quot; hack is now officially supported: since some versions of ASP.NET don&#039;t allow directories beginning with dot (e.g., &quot;.svn&quot;, the standard Subversion working copy administrative directory), TortoiseSVN now treats the environment variable SVN_ASP_DOT_NET_HACK specially. If this variable is set (to any value), it will use &quot;_svn&quot; instead of &quot;.svn&quot;. Note that once the environment variable is set, working copies with standard &quot;.svn&quot; directories will stop working, and will need to be re-checked-out to get &quot;_svn&quot; instead. 

簡單的說,只要設置環境變數:SVN_ASP_DOT_NET_HACK 就行了.
不知道  subversion  是不是也是一樣的設置方法.
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/986619.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 11 Jan 2006 17:12:38 +0800</pubDate>
					</item>
	<item>
		<title>Mono and Fedora Core 5 / Thinking more...</title>
		<description>今天看到令人高興的消息: Mono and Fedora ,Mono 將會被包含在 Fedora Core 5 裡面了...
真是棒啊!
文章裡面也提到了不少 tutorial 的文章喔.





</description>
		<link>http://blog.roodo.com/thinkingmore/archives/986601.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 11 Jan 2006 17:08:19 +0800</pubDate>
					</item>
	<item>
		<title>mono 與 SELinux / Thinking more...</title>
		<description>重灌 server 並啟用 SELinux 以後,發現 asp.net 應用程式無法啟動.
原本不想碰 SELinux 的,不得已,出來混的早晚都要還,只好硬著頭皮去K.

經過研讀文件之後,大致上對 SELinux 有一定的瞭解.
SELinux 本身純粹是作安全性的加強,所以不管是 user, file, directory, socket, process...等等的,都另外有了 security context,作為安全性的第二道防線.
當系統要存取這些資源的時候,首先會使用原有的 unix permission 去作檢查,接著 SELinux 會再依照 security context 作第二道檢查,當檢查沒問題之後,才會允許存取.

SELinux 裡面有所謂的 identity, domain, type, security context, target context 等等物件...
大致上來說, identity 決定身份, domain 決定 process 能幹麼, type 決定 process 以外的物件可以幹麼, security context, target context 則是 identity + domain + type 的組合. policy 則用來定義 security context, target context 可以存取哪些物件. (這些組合,真的很讓人頭暈.)

存取的指令也蠻多的:  要看檔案目錄的 security context, 可以加上 -Z (ls -Z)  要看process的 security context, 也可以用 -Z (ps axZ)  要看自己的security context,可以用 id  要改security context, 可以用 chcon  要 reset security context, 可以用 restorecon  ...  

整個研讀完之後,發現應該是 policy 問題.
今天下午用 Google 去找到  v14, i08: Tuning Your SELinux Policy with Audit2allow&quot; href=&quot;http://www.samag.com/documents/s=9820/sam0508a/0508a.htm&quot;&gt;這篇文章 ,發現有這麼個工具 - audit2allow,他是在 policycoreutils 套件裡面的指令,可以根據 warning message 產生 policy,省掉不少編寫的麻煩.

為了要能重新編譯 policy, 你需要安裝 selinux-policy-targeted-sources 這個套件
 yum install selinux-policy-targeted-sources 

再使用 audit2allow 這個指令,從 dmesg 裡面分析 warning, 並將產生以後的 policy 寫入到 mono.policy 檔案中.
 audit2allow -d -o mono.policy 
接著把 mono.policy 更名為 local.te, 放到 /etc/selinux/targeted/src/policy/domains/misc/ .
放完之後,切換到 /etc/selinux/targeted/src/policy
強制 selinux 重新編譯 policy
 make load 
最後重新啟動我的  Apache  server,就大功告成了.

參考資料:
   Getting Started with SE Linux HOWTO: new SE Linux         Writing SE Linux Policy HOWTO         Fedora Core 3 SELinux FAQ    SETools policy tools for SELinux ,SELinux utility的介紹       An overview of object classes and permissions 很完整的 selinux 物件與權限.        v14, i08: Tuning Your SELinux Policy with Audit2allow&quot; href=&quot;http://www.samag.com/documents/s=9820/sam0508a/0508a.htm&quot;&gt;Tuning Your SELinux Policy with Audit2allow   </description>
		<link>http://blog.roodo.com/thinkingmore/archives/978381.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 09 Jan 2006 22:06:55 +0800</pubDate>
					</item>
	<item>
		<title>ThreadAbortException / Thinking more...</title>
		<description>原來呼叫 Response.End() 就會丟出 ThreadAbortException.
害我以為是我程序出現錯誤了呢...

請  Google  幫忙一下,原來也有人碰到同樣情況:
 Impersonation Failure : ASP.NET - ThreadAbortException 
其實還不只是 Response.End(), Server.Transfer() 與 Response.Redirect() 也有機會發生此狀況,因為他們內部也呼叫了 Response.End().

比較正確的作法應該還是先呼叫 Response.Flush();
Response.Close();
 
會比較好些.

這是那篇文章所提供的參考資料:   http://support.microsoft.com/default.aspx?scid=kb;en-us;q312629    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwebhttpresponseclassredirecttopic2.asp    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwebhttpresponseclassendtopic.asp   
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/964720.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 06 Jan 2006 16:47:23 +0800</pubDate>
					</item>
	<item>
		<title>log4net / Thinking more...</title>
		<description>
在 .Net/mono 程序裡面使用 log4net,是極為簡單的事情.
首先到  log4net 官方網站 下載 .
解開以後,到 bin 資料夾下,找適合你用的 assembly file. (p.s. 其實也不用特別找, .Net 與 mono 是通用的, .Net compact framework 與 sccli 我就沒試過了)
接著,視你自己專案的類型,該引用的就引用 (Visual Studio.Net/MonoDevelop/SharpDevelop),該改 Nant build file / Makefile 的就改.

步驟一:
使用  log4net  的第一步,是在你程序一開始的地方,去解析  log4net  的 configuration.
 log4net.Config.XmlConfigurator.Configure(); 
一般性的 Windows form 程序通常是放在 Main 的一開始,而 asp.net 程序通常則是在 global.asax (codebehind 的話就是 global.asax.cs) 的 Application_Start 事件.

步驟二:
接著在你想要進行 log 的類別宣告這一個屬性.
 protected static readonly ILog log = LogManager.GetLogger(typeof( your_class_name )); 
要當成一般變數來用也行
 ILog log = LogManager.GetLogger(typeof( your_class_name )); 

步驟三:
最後是在你想要 log 的地方,放置這麼一行
 log.Info( &quot;your message here.&quot; ); 
大功告成!!

就這麼簡單.

而 ILog 不只 Info() method 可以操作,還可以有 Debug(), Error(), Fatal(), Warn() 這幾個 method 可用,他們各代表了不同的層級.
層級的區分大致是這樣: Debug &amp;lt; Info &amp;lt; Warn &amp;lt; Error &amp;lt; Fatal
換句話說,當你 Configuration 裡的層級設定為 Debug 的時候,只要你有調用 ILog 的任何一個 method 來 log, 這些訊息都會出現在 log 裡面.
當你 Configuration 裡的層級設為 Warn 的時候,你有調用 Warn(), Error(), Fatal() 這三個 method 來 log 的地方,這些訊息都會出現在 log 裡面.

再來就是 Configuration.
Windows form 的 configuration 檔案通常名稱是 xxx.exe.config, asp.net 的 configuration 檔案則是 web.config
這裡主要放置兩個部份:
 
  configSection:
 &amp;lt;configSections&amp;gt;
    &amp;lt;section name=&quot;log4net&quot; type=&quot;log4net.Config.Log4NetConfigurationSectionHandler,log4net&quot; /&amp;gt;
&amp;lt;/configSections&amp;gt;
 p.s.這裡我有一個慘痛的教訓,查了好久,結果發現是打錯字, &quot;log4net.Config&quot; 我打成 &quot;log4net.config&quot;,一度我還懷疑是 configuration file 問題,還跑去 trace log4net 的程式 =_=&quot;, 如果你確定你都設對了,該設的也都設定了,不妨利用 LogManager.GetRepository 取得 ILoggerRepository,去看 Configured 屬性,如果是 false,表示沒設定到,可以試著檢查大小寫看看.  
  log4net, 這邊請參考  log4net Config Examples  會比較快一點.  
 

參考資料:
   Using Apache&#039;s log4net in ASP.NET    Diagnostics and Logging In ASP.NET    Example of using log4net   </description>
		<link>http://blog.roodo.com/thinkingmore/archives/957222.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 04 Jan 2006 23:24:46 +0800</pubDate>
					</item>
	<item>
		<title>關於 ASP.NET 的 Cache(後續追蹤報導) / Thinking more...</title>
		<description>昨天在 Trace ASP.NET Caching 之後,還是念念不忘...
這麼好用的 OutputCacheModule 為甚麼會需要特別設定才會掛載??

於是今天再次 Trace, 這次從 Page 的產生開始.
於是我下手查了  Mono  的 PageCompiler 與 PageParser
他們之間的 Class diagram 大致是這樣
   

在收到 Page Request 的時候,如果以前沒編譯過,Page Compiler 會先 Parse 這個 Page, 接著組出 code, 動態編譯成組件 (Assembly),然後再載入這個組件.
這樣一查下來,發現 PageParser 遇到 @ OutputCache 這個 Directive 的時候,也沒有動態去載入 OutputCacheModule 這個 Module.

這更怪了,再搜索 HttpModuleCollection.AddModule (.Net 是 HttpModuleCollection.LoadModule ),發現這真的只有在 HttpApplication 一開始的時候才有用到.
難道我昨天的結論真的沒有錯??

在萬念俱灰之下,利用 Google 搜索 OutputCacheModule
找到這篇文章: Extending the ASP.NET Runtime with Custom HTTP Modules 

才發現,除了應用程式自訂的 web.config 之外,其實還有預設的 .config !!
以 .Net 1.1 來說,他是在 %WINDIR%\Microsoft.NET\Framework\v1.1.4322\CONFIG\machine.config
以  Mono  來說,他是在 /etc/mono/1.0/machine.config

打開來看之後,赫然發現在這裡, OutputCacheModule 已經被載入了!
所以並不需要特別在你自己的 web.config 去加載 OutputCacheModule!!

p.s. 這篇是意外的收穫,對於整個流程解析的不錯,僅供參考: ASP.NET 中 Session 實現原理淺析 (1) 會話的建立流程 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/870756.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 16 Dec 2005 14:41:33 +0800</pubDate>
					</item>
	<item>
		<title>關於 ASP.NET 的 Cache / Thinking more...</title>
		<description>一般人大概會想,這有甚麼好說的,不就是在頁面加上 @ OutputCache 指示詞(Directive), 這樣就表示會快取頁面.

列在 .Net framework SDK documentation 裡的詳細語法:
 &amp;lt;%@ OutputCache Duration=&quot;#ofseconds&quot; Location=&quot;Any | Client | Downstream | Server | None&quot; Shared=&quot;True | False&quot; VaryByControl=&quot;controlname&quot; VaryByCustom=&quot;browser | customstring&quot; VaryByHeader=&quot;headers&quot; VaryByParam=&quot;parametername&quot; %&amp;gt;
 

或許吧,這沒啥大不了的,但我好奇的是,背地裡,.Net 是怎麼幫我完成這件事情的呢??
從 .Net Framework SDK documentation 裡面,幾乎無法找到相關資訊,解釋得很籠統.
於是我只能作這些猜想:
1. .Net 利用 HTTP/1.1 的 Caching 來實現.
2. 內部再使用 Cache hashtable 來避免對後端過於頻繁的存取.例如,取得資料以後,先放到 Cache,如果 Cache 裡面找的到(表示沒過期),就直接拿來顯示,否則的話就再去取資料.

我對第二點沒什麼意見,實際上應該是要這麼作.
但是第一點,我就有問題了.  HTTP/1.1 的 Caching 機制對 server 端來說,server 只是送出特定的 HTTP header, 如 Cache-Control, Expires 等等. (參見  HTTP/1.1: Caching in HTTP  ).
對 client 來說,他收到這些 header, 怎麼實做,反而是看他自己.如果是坊間抓網頁程式,他可以忽略這些 header, 卯起來抓,那麼這樣就沒有 cache 的效果啦~
另外一點,我感到懷疑的,在他語法裡,可以指定 Any/Client/Downstream/Server, 所謂的 Server, 又是指甚麼意義呢?

就我自己的認知,應該是 Server 在處理的時候,會把整個頁面放到 Cache 裡面.
當遇到有人索取這頁面的時候,就會檢查 Cache, 如果有就直接取出.

所以我查找 Mono 與 .Net 解釋 HttpApplication 的部份,他們都特別指出了 HttpApplication 收到 web request 以後處理的順序:
 1. BeginRequest
2. AuthenticateRequest
3. AuthorizeRequest
4. ResolveRequestCache
5. AcquireRequestState
6.PreRequestHandlerExecute
7.PostRequestHandlerExecute
8.ReleaseRequestState
9.UpdateRequestCache
10.EndRequest
 
特別注意步驟 4 與步驟 9, 他們都提到了 Cache.
p.s. 我覺得  Mono Framework class reference  寫的比較清楚, 參閱  HttpApplication 

接著,我又利用  Google  查找相關資訊.
發現有用 mono 應用程式的 web.config 多半都會加掛 OutputCacheModule 這個 Module.
 &amp;lt;httpModules&amp;gt;
    &amp;lt;add name=&quot;OutputCache&quot; type=&quot;System.Web.Caching.OutputCacheModule&quot;/&amp;gt;
&amp;lt;/httpModules&amp;gt;
 

參考  mono  的源碼以後,發現這就是我要找的.
這個 Module 的確做了我推想的事情.
他在 OnResolveRequestCache 事件先依據 FilePath 去檢查 Cache, 如果存在,就直接以 Cache 內保存的內容輸出.
接著在 OnUpdateRequestCache 事件,檢查頁面是否需要被 Cache, 需要的話,就把輸出結果保存到 Cache 中.

Bingo!!
但這是 mono 的作法, .Net 是否也有同樣的類別呢??
我利用 Reflector  這個工具去看 System.Web.dll, 的確, 有 OutputCacheModule 這個 Module.

至此,我們已經解決了我想要解決的問題,並做出一個小結論:
如果想對頁面作 Cache 的話,需要作兩件事情:
1. 在頁面的開始加上 @ OutputCache 指示詞.
2. 在 web.config 裡面加掛 OutputCacheModule

可是我接下來想知道的是,如果我用 .Net 去寫作的時候,也需要特別加掛這個 Module 嗎??
再次求助於  mono  的源碼, 從 HttpApplication.cs 開始查找.
我直接搜索 HttpModule, 因為我想知道 HttpApplication 是在何時載入 Module.
HttpApplication 正巧有一個 HttpModuleCollection, 這看來就是 HttpModule 的 Collection.
宣告的名稱為 modcoll, 接著以 modcoll 進行搜索.很快就找到 InitOnce, 這裡以 ModulesConfiguration 對 modcoll 進行了初始化.
接著再查看 ModulesConfiguration 與 HttpModulesConfigurationHandler 的源碼, 至此已經真相大白.
原來如果沒有在 web.config 指定要掛載的 module 的話,只會掛載內定的 DefaultAuthenticationModule.

那麼微軟的 .Net 呢??
以  Reflector  查找同樣的 Class, 並進行 disassembly.
果然也做了一樣的事情,沒指定要掛載的 module 的話,只會掛載內定的 DefaultAuthenticationModule.

補充結論:
除了小結論所提到的事項之外,一定要在 web.config 裡面指定要掛載 OutputCacheModule, 才會更能發揮 Cache 的功效.

參考資料:
* HTTP/1.1: Caching in HTTP 
* Caching in ASP.NET 
* Page Output Caching, Part 1 
* ASP.NET Caching 
* mono 的源碼
*.Net framework SDK documentation
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/867191.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 15 Dec 2005 16:41:49 +0800</pubDate>
					</item>
	<item>
		<title>給定 assembly strong name 的方法 / Thinking more...</title>
		<description>給定 assembly strong name 的方法
1.sn -k &quot;your_snk.snk&quot;
2.在你的 AssemblyInfo.cs 裡面加上
[assembly: AssemblyKeyFile(@&quot;your_snk.snk&quot;)]
3.編譯,收工.

Mono 也有同樣的指令,用法也完全一樣.
不再贅述.
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/833840.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 07 Dec 2005 12:49:38 +0800</pubDate>
					</item>
	<item>
		<title>混合編譯vb.net與c# / Thinking more...</title>
		<description>上次有人有在討論區問到怎麼混合編譯 vb.net 與 c# 的程式.
那時唯一的好解法,就是將 vb.net 程式編譯為 assembly
c# 程式也編譯為 assembly,這樣就能交互引用了.
這樣的缺點是,assembly 會比較多一些.
今天在 CodeProject 逛到這篇: Post build step static linking tool for C#, using ILMerge ,恰好就可以解決此問題.
他引用了 微軟研發 的 ILMerge 來作合併的工作.
不過很可惜的是, ILMerge 目前還不能在 Mono 上使用.
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/833828.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 07 Dec 2005 12:44:10 +0800</pubDate>
					</item>
	<item>
		<title>c# / PostgreSQL / unicode / Thinking more...</title>
		<description> Yuren’s Info Area 提到了 c# 連結 PostgreSQL 的部份: [tip] 解決 C# 連結 PostgreSQL 的中文問題 

connect string 要記得加上 encoding=unicode
 NpgsqlConnection conn = new NpgsqlConnection(”Server=localhost;Port=5432;Encoding=UNICODE“);
 

收錄起來...
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/829257.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 06 Dec 2005 10:26:08 +0800</pubDate>
					</item>
	<item>
		<title>其實是通用的... / Thinking more...</title>
		<description>本來以為, .Net 編譯出來的東西與  mono  是不通用的.
可是很奇怪,在網路上都找不到相關的文件來解釋為甚麼  nant  用  mono  編譯會有警告/錯誤或是為甚麼  nhibernate  用  mono  編譯會有警告/錯誤之類的問題.
照理來說,如果是很常見的問題,都應該早有人問了才對.
昨天,赫然發現,其實是通用的.
我用  .Net Framework 1.1  編譯好一個簡單的 hello world 程式,然後放到 linux 上,以  mono  執行.
果然可以執行...
換句話說...... 我是豬頭 ......
早就該想到了,如果都 follow ECMA 的標準,其實都是通用的才對!!!
真是笨.
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/778810.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 25 Nov 2005 12:38:34 +0800</pubDate>
					</item>
	<item>
		<title>初探NUnit / Episode 8ight</title>
		<description>      今天在Starbucks看書，讀到有關Software Testing部分時，突然想到NUnit這個東西，乾脆就去downlaod回來試用看看。老實說至今還沒有接觸過NUnit，這應該算是蠻popular、basic的unit 
  test工具；身為一個programer卻從沒有真正做過unit test實在有點丟臉，趁這個機會接觸一下。 
  NUnit 應該算是由JUnit（java所使用的Unit Test工具）所porting過來的一套工具，專用來為.Net做單元測試（Unit Test）使用，所謂單元測試，應該是指針對程式中的基本單位－物件、方法或是模組進行輸入輸出或執行結果做正確性測試。安裝NUnit後，我直接參考裡面所附的sample檔案，提供的GUI工具也相當的簡單。 </description>
		<link>http://blog.roodo.com/mosa/archives/777723.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 25 Nov 2005 00:57:36 +0800</pubDate>
					</item>
	<item>
		<title>mod_mono AutoConfiguration / Thinking more...</title>
		<description>Mono 1.1.10 前幾天 release 了,在 asp.net 方面,多了一個很方便的功能 -  AutoConfiguration .
在之前,每次添加一個 asp.net application, 就需要去更動 mod_mono 設定,相當麻煩.
現在可以不用了,只要在 mod_mono.conf 添加
 MonoAutoApplication enabled 
之後,就可以很方便的跟寫 php application 一樣,建立目錄以後,就等同於是建立 application.

舉例來說,你在你的 Home directory 編修一個 asp.net 網頁
 
$ echo $USER
rupert
$ cd
$ cd public_html
$ mkdir demo
$ cd demo
$ edit hello.aspx
 
那麼,你編寫完以後,就可以直接
 http://your_server/~rupert/demo/hello.aspx 

真的是...太方便啦... :)
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/746742.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Sat, 19 Nov 2005 10:04:56 +0800</pubDate>
					</item>
	<item>
		<title>Mono Directions / Thinking more...</title>
		<description>今早在 LinuxToday 上看到 Mono Directions ...
裡面報導了目前的現況,以及未來的方向.

我只摘錄我有興趣的幾個項目:
*mono 1.2 要等到 Windows.Form 完備以後才 release
*gmcs (.Net 2.0 c# compiler) 除了 nullable types 之外,已經齊全.
*monodevelop, 可以寫 plugin 來 enhance 了,我最期待的是 asp.net designer...
*asp.net 2.0 在進行中,但已經有不少 control 可用,而 Atlas 也開始實做.
*msbuild 也有替代品 - xbuild...但還沒作為正式 release 的內容 (Google Summer of code projects 的成品)
*xaml 也有人實作了. (Google Summer of code projects 的成品)
*ADO.Net 2.0 進行中.

其他又學到的,原來有  mono debugger 可用...
介面非常類似 gdb,對熟悉 linux 程式寫作的人,不難上手.
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/746694.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Sat, 19 Nov 2005 09:42:54 +0800</pubDate>
					</item>
	<item>
		<title>.Net attribute / Thinking more...</title>
		<description>attribute, 用來為 class, method, parameters 貼上標籤,以便後續的應用.
所有的 attribute class 都要繼承 System.Attribute

 class Class1Attribute: System.Attribute
{
}
 

使用的時候可以省略 Attribute
 [Class1]
class Class2
{
}
 

打全名當然也是可以
 [Class1Attribute]
class Class2
{
}
 

使用 xxx( yyy ) 時,attribute 的 constructor 會被套用,而 attribute class 裡的 property 會被自動認定為 named parameter.
 class Class1Attribute: System.Attribute
{
	private int _id;
	private string _name;

	public Class1Attribute( int id )
	{
		_id = id;
	}

	public string Name
	{
		get { return _name };
		set { _name = value };
	}
}
[Class1( 1, Name=&quot;This is a test&quot; )]
class class2
{
}
 

也可以貼很多標籤上去
 [AttributeUsage(AttributeTargets.Class, AllowMultiple=true)]
class Class1Attribute: System.Attribute
{
   ....
}
[Class1( 1, Name=&quot;This is a test&quot; ), Class1( 2, Name=&quot;Test2&quot; )]
class class2
{
}
 

但是要怎麼應用呢? 從 .Net framework documentation 裡的 sample, 大致上可以猜到.
 using System;
using System.Reflection;

namespace CustomAttrCS {
    // An enumeration of animals. Start at 1 (0 = uninitialized).
    public enum Animal {
        // Pets.
        Dog = 1,
        Cat,
        Bird,
    }

    // A custom attribute to allow a target to have a pet.
    public class AnimalTypeAttribute : Attribute {
        // The constructor is called when the attribute is set.
        public AnimalTypeAttribute(Animal pet) {
            thePet = pet;
        }

        // Keep a variable internally ...
        protected Animal thePet;

        // .. and show a copy to the outside world.
        public Animal Pet {
            get { return thePet; }
            set { thePet = Pet; }
        }
    }

    // A test class where each method has its own pet.
    class AnimalTypeTestClass {
        [AnimalType(Animal.Dog)]
        public void DogMethod() {}

        [AnimalType(Animal.Cat)]
        public void CatMethod() {}

        [AnimalType(Animal.Bird)]
        public void BirdMethod() {}
    }

    class DemoClass {
        static void Main(string[] args) {
            AnimalTypeTestClass testClass = new AnimalTypeTestClass();
            Type type = testClass.GetType();
            // Iterate through all the methods of the class.
            foreach(MethodInfo mInfo in type.GetMethods()) {
                // Iterate through all the Attributes for each method.
                foreach (Attribute attr in Attribute.GetCustomAttributes(mInfo)) {
                    // Check for the AnimalType attribute.
                    if (attr.GetType() == typeof(AnimalTypeAttribute))
                        Console.WriteLine(
                            &quot;Method {0} has a pet {1} attribute.&quot;, 
                            mInfo.Name, ((AnimalTypeAttribute)attr).Pet);
                }
            }
        }
    }
}
 

所以你可以看到,在貼上標籤以後,其實對 Class 本身來說沒啥作用,會認為有用的,是其他的 Class, 他們可以依據這些 Attribute 來作一些特定的處理.

這邊有一系列的文章,還提出了應用.   博客园 - dudu - Attribute在.net编程中的应用（一）    博客园 - dudu - Attribute在.net编程中的应用（二）    博客园 - dudu - Attribute在.NET编程中的应用（三）    博客园 - dudu - Attribute在.NET编程中的应用（四）    博客园 - dudu - Attribute在.NET编程中的应用（五）    博客园 - dudu - Attribute在.NET编程的应用（六）   

系列 2~4 介紹一個 sql generator 的範例.
系列 5~6 是一個比較深的範例,牽涉到 Remoting 的東西

.Net framework 內也預定了不少 Attribute,我覺得還蠻有用的.
例如: Conditional attribute

以下面的範例來說,如果 DEBUG 沒被定義,那麼 Class1.M() 將不會被執行.
這倒是一個不錯的debug方法
 #define DEBUG
using System;
using System.Diagnostics;
class Class1
{
	[Conditional(&quot;DEBUG&quot;)]
	public static void M() {
		Console.WriteLine(&quot;Executed Class1.M&quot;);
	}
}
class Class2
{
	public static void Test() {
		Class1.M();
	}
}
 

仔細想想也可以用來作版本控管喔...某版本可以用這個 method, 但是某版本不行....

還有就是 Obsolete, 可以用來指示 class 或 method 即將被淘汰
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/736060.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 17 Nov 2005 13:24:00 +0800</pubDate>
					</item>
	<item>
		<title>Mono XSP 與 SSL / Thinking more...</title>
		<description>今天逛到的,Mono XSP 也可以支持 SSL,先收錄起來.
* UsingClientCertificatesWithXSP - Mono 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/715114.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Sat, 12 Nov 2005 11:34:44 +0800</pubDate>
					</item>
	<item>
		<title>Regex 101 Exercise / Thinking more...</title>
		<description>Today, I found an  article - Eric Gunnerson&#039;s C# Compendium : Regex 101 Exercise S3 - Validate a zip+4 zip code .

I think that I can practice my regular expression skill.

How to match these patterns using .Net regular expression??
98008
98008-4893

My answer is:
[0-9][0-9][0-9][0-9][0-9]-?[0-9]*

It seems stupid.  There should be better solution.
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/694549.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 08 Nov 2005 10:11:12 +0800</pubDate>
					</item>
	<item>
		<title>Mono 與 GNU GetText / Thinking more...</title>
		<description> Debian Wiki 上有提供  Mono 的中文簡介說明 ,裡面有提到與  GNU GetText  合作的方法.

 GNU GetText  是 Linux 世界裡作 i18n/l10n 的一組 library.
這意味著  mono  也可以藉由 GNU GetText 來達到 i18n/l10n.

 mono 網站上提供了詳細的 Tutorial 可供參考.
以 .Net 本身來說,一般使用的方法是 Resource,原理差不多.
該怎麼選擇,就看開發者個人囉.
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/692780.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 07 Nov 2005 22:18:51 +0800</pubDate>
					</item>
	<item>
		<title>Delete via DataAdapter / Thinking more...</title>
		<description>這是一個慘烈的教訓,我搞了一天半.
我始終不明白,爲什麼我確實地在 DataSet 裡的 DataTable 去刪掉了一筆 DataRow, 但 Update 的時候卻無法成功?

Open source 就是有這好處,於是我開始 Trace  mono  的 ByteFX.Data.

大致看了一下,發現幾件有趣的事情:
*在我們呼叫 xxxDataAdapter.Update 的時候,其實是呼叫 DbDataAdapter.Update.各個 Provider 並不負責這件事情.各個 Provider 是負責提供必要的資訊給 DbDataAdapter, 讓她去完成這件事情.
*xxxDataAdpater 的 DeleteCommand, InsertCommand, UpdateCommand 在
xxxDataAdapter da = new xxxDataAdapter(); xxxCommandBuilder xcb = new xxxCommandBuilder( da ); 的時候並不會被馬上組出來,而是在內部被呼叫 RowUpdating (真正要 Update)的時候,才被組合出來.

這些都跟主旨無關.回到正題.爲什麼無法刪除呢??
我使用的語法是這樣子,在我找到我要刪除的 DataRow 之後,我使用的是 DataTable.Rows.Remove( 我要刪除的row ).
很不幸,這會直接從 DataRowCollection 裡面直接刪掉.
但是 DbDataAdapter.Update 依賴的是 DataRowCollection 裡面各個 Row 的 RowState 來判定要新增,修改或是刪除. 如果 DataRowCollection 裡面並沒有這個 DataRow,那麼 DbDataAdapter.Update 也不會知道這個 DataRow 需要被刪除.
因此你在找到要刪除的 DataRow 之後,得用 DataRow.Delete() 才行.
這邊需要特別注意的是, Delete() 之後,不要使用 DataTable.AcceptChanges(),這個命令同樣會使得 DataRowCollection 採取和 Remove() 一樣的動作.
Delete() 之後再呼叫 xxxDataAdapter.Update(), 這樣就可以順利完成刪除動作了.
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/691002.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 07 Nov 2005 15:22:30 +0800</pubDate>
					</item>
	<item>
		<title>PageIndexChanged on mono 1.1.9.2 / Thinking more...</title>
		<description>原本以為是我程序上的錯誤,但並不是.

情況是這樣的,我想要在  mono  1.1.9.2 上使用 DataGrid 的分頁功能.
因此我複寫了 PageIndexChanged 事件.
總共有 2x 筆資料, PageSize 設為 10, 因此共會出現 3 頁.
但只要我點選最後一頁,網頁就會丟出例外:
System.IndexOutOfRangeException: Array index is out of range.

搜索了一下,發現這個錯誤已經被回報了: Bug 76503 ,並且已經於 svn HEAD r52068 修正掉了.
可惜現在不能試.
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/690956.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 07 Nov 2005 15:12:10 +0800</pubDate>
					</item>
	<item>
		<title>RSS 時刻表 (feedgator) / Thinking more...</title>
		<description>目的:收集 feed, 然後依照時間顯示最近的 50 筆
主要部份:
1. Crawler, 抓取 feed, 並安插到 Database
1.1 Remover, 週期性刪除,刪除資料庫中超過 30 天或特定天數的 feeds ( This is setting is in web.config, FeedExpiredDays )
2. 主頁面, 從 database 取資料出來顯示
3. Manage:
3.1 新增 feed url
3.2 編輯/修改 feed url 資料

Table 規劃:
feeditem ( author, guid, link, pubdate, title )
feedurls ( link, lastbuild )

其他事項:
1. 頁面美觀, 可以參考  lilina ; 另外記得 DataGrid 可以做 grouping.
2. manage 部份可以引進 tab panel, 這樣就可以把 add 與 browse/edit/delete 放在一起了
3. 是否要支援 log4net 來存放 crawler 的 log??
4. 支援 atom?

後記:
其實這個小 project 已經進行一段時間了,都是間斷的寫...到現在還沒弄完...
寫的過程裡面學到不少東西:
1. Mono xsp 可以直接在 httpd 的 configuration 中設置就好(/etc/httpd/conf.d/mono.conf), httpd 會負責把 xsp(mod-mono-server) 叫起來.沒有以前那麼麻煩了.
2. Mono xsp 的 default encoding 需要在環境變數中指定, mod_mono 的設定裡面可以指定 (MonoSetEnv &quot;LANG=en_US.UTF-8&quot;),否則將會是 Apache 的預設 encoding (ASCII)
3. RSS 的 pubdate 用的是 universal time, 而非 local time.
4. MySQL 3.x 不支援 unicode, 或者應該說, bytefx.Data mysql data provider 會依賴 MySQL database 內的 codepage 設定來決定是否要轉碼,而 php mysql library 並不會.
5. nHibernate 尚未移植到  Mono 

參考資料:
* Mono 
* Mod_mono&quot; 
* RSS.NET: An open-source .NET class library for RSS feeds 
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/639503.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 26 Oct 2005 19:26:05 +0800</pubDate>
					</item>
	<item>
		<title>Mono ByteFX.Data 與 encoding / Thinking more...</title>
		<description>ByteFX.Data 是  MySQL  的 .Net Data Provider, 同時提供有  mono  與  Microsoft.Net  的版本(微軟版本好像叫做  Connector/.Net ).
這兩天在試著用  mono  與 ByteFX.Data 來存取  MySQL  資料庫.
但卻發現中文的字串在存入資料庫之後,全部都變成問號了.
原本以為是我編碼的處置或設定有問題,在經過 Trace  mono  與 ByteFX.Data 的 source code 之後,才發現並不是.
我開始懷疑是  MySQL  的問題,我首先去問  Google  大神.
 Google  大神告訴我, MySQL  在 4.0 以前並不支援 unicode, 資料庫預設的編碼是 latin1.
ok, 那麼為什麼使用  MediaWiki  或是一些 blog 卻可以存入 unicode 的字串??
又稍稍的 Trace 了  MediaWiki  的 source code, 並無驚人之處,也沒有什麼特別的處理,純粹就是 insert, update 而已.

最後我再回頭看 ByteFX.Data 的 source code, 終於找到問題所在.
ByteFX.Data 在丟封包到  MySQL  之前,會先依據  MySQL  的 encoding 進行編碼.
所以不管怎麼樣,我在 client 怎麼轉碼,到最後 ByteFX.Data 都會轉成 latin1,再進行存入.

是故,可能的解法如下:
1. 升級  MySQL  到 4.0 以後的版本.
2. 在丟資料庫之前,先把字串轉為 byte[], 如果是 byte[], ByteFX.Data 就不會進行轉碼,而直接存入. 但這樣在取出資料的時候,還需要再作一次工,將 byte[] 轉回 string.

解法 2 相當費事,而且以後如果要更換資料庫的時候,又會再受到一次衝擊.
看來解法 1 才是王道. 但是,懶得升級說... =_=
</description>
		<link>http://blog.roodo.com/thinkingmore/archives/566961.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 07 Oct 2005 11:39:22 +0800</pubDate>
					</item>
	<item>
		<title>在 .Net 指定 proxy 的方法 / Thinking more...</title>
		<description>其實只要在 Machine.config (也就是 xxx.exe.config) 裡面指定就可以了.
範例如下:
&amp;lt;configuration&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;lt;system.net&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;defaultProxy&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;proxy
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxyaddress = &quot;http://proxyserver:80&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bypassonlocal = &quot;true&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/defaultProxy&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;lt;/system.net&amp;gt;
&amp;lt;/configuration&amp;gt;

此方法, .Net 與 mono 均適用.

參考資料:
* dotnetJiNi.com - Blogs @ Jignesh Desai </description>
		<link>http://blog.roodo.com/thinkingmore/archives/563376.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 06 Oct 2005 13:24:31 +0800</pubDate>
					</item>
	<item>
		<title>The LINQ Project(心得) / Thinking more...</title>
		<description>懶得把 LINQ 裝起來試....
目前只把 LINQ 與 DLINQ 的 overview 看完而已...

這邊做一個簡單的說明
LINQ ,實作類似 SQL Query 的語法來操作 collection
DLINQ, 解決 Relational DB 與 collection 之間的轉換與對應.
XLINQ, 解決 XML 文件與 collection 之間的轉換與對應.
VFP, 以 SQL Query 直接操作工作區或 Relational DB

看出 LINQ 與 VFP 的不同了嗎??
VFP 的確很強大,已經把 Query 資料庫的技術發揮到極致,但缺點是很難對應到物件導向世界,物件導向的世界裡面一切都是物件,只有 class / object, 而沒有 database. 很多同類的物件在一起,是 collection, 是 container, 而不是 database.
LINQ 則是直接對 collection 操作.

目前很多人對 DLINQ 頗有微詞的地方,是在於 DLINQ 使用了 attribute 去為 class 的 member 貼上資訊,在與 Relational DB 對應的時候,就依照這些 attribute 來做對應.這樣會使得相依性過高.
這部份,我也不知道怎麼樣會是比較好,但 nHibernate 看起來是一個不錯的選擇.

其他可以參考的開源ORM專案:
* Gentle.NET 
* iBatis 
* nHibernate </description>
		<link>http://blog.roodo.com/thinkingmore/archives/554319.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 27 Sep 2005 22:11:55 +0800</pubDate>
					</item>
	<item>
		<title>The LINQ Project(補) / Thinking more...</title>
		<description>剛剛用  Google  新推出的  Google blog search  去找
發現了一大堆...
 http://www.google.com/blogsearch?hl=en&amp;q=LINQ&amp;btnG=Search+Blogs&amp;filter=0&amp;sa=N&amp;start=10 

這篇文章的標題: Project LINQ - Can it be done in VFP? 
還蠻吸引我的...
果然裡面又批了微軟一頓
還寫了一個程序&quot;Visual FoxPro Object-Oriented SQL (VOSQL)&quot;來證明 VFP 的強大.

其他參考資料:
* Linq and C# 3.0 
* Language Integrated Query (LINQ) feedback 
* Project LINQ and XML - Some reflections 

Another, c# 3.0 對 functional programming 的新寫法
* Functional programming in C# - Reloaded! </description>
		<link>http://blog.roodo.com/thinkingmore/archives/554316.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 16 Sep 2005 11:30:33 +0800</pubDate>
					</item>
	<item>
		<title>The LINQ Project / Thinking more...</title>
		<description>昨天在微軟那兒逛到的新東西,本想搶先介紹的,可是還沒看完只好作罷.
沒想到今天就已經有人介紹了...
 LINQ: a post-modern revolution in software development 
 預覽.NET 3.0未來版本 

以下的範例對 VFP developer 來說,可能會發出會心的一笑.
 Northwind db = new Northwind(&quot;c:\\northwind\\northwnd.mdf&quot;);
var q =
      from c in db.Customers
      where c.City == &quot;London&quot;
      select c;
foreach (var cust in q)
      Console.WriteLine(&quot;id = {0}, City = {1}&quot;,cust.CustomerID, cust.City);
 
這跟 VFP 的
 select c.* from Customers c where c.City==&quot;London&quot; into array q 
有什麼不一樣呢??

接下來得找一些時間裝起來研究一下.

參考資料:
* The LINQ Project 
* Samples </description>
		<link>http://blog.roodo.com/thinkingmore/archives/554314.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 15 Sep 2005 09:40:35 +0800</pubDate>
					</item>
	<item>
		<title>VS.Net bug / Thinking more...</title>
		<description>錯誤訊息:&quot;Refreshing the project failed. Unable to retrieve folder information from the server.&quot;

果然早有人遇到此問題...
這是因為 Visual Studio.Net 無法接受 .svn, 也就是以 &#039;.&#039; 開頭的目錄名稱.
所以他發出哀號.

解決方法:
改下載另外一個特別版本的  tortoisesvn , 他在 checkout 之後,不會使用 &quot;.svn&quot;,而改以 &quot;_svn&quot;.這樣就解決問題了...

參考資料:
 
 
 VS.NET 2003, VSS 6.0d and the &quot;Refreshing the project failed. Unable to retrieve folder information from the server&quot; error  
  Annoying VS.NET Bug  
 </description>
		<link>http://blog.roodo.com/thinkingmore/archives/554312.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Sun, 11 Sep 2005 22:37:36 +0800</pubDate>
					</item>
	<item>
		<title>&#039;@&#039; in c# string literal / Thinking more...</title>
		<description>為什麼網路上很多範例都會在字串前面加上 &#039;@&#039; 呢??
幸好有 c# specification , 這才解答了我的疑惑...
 c# specification 裡面對此有相當多的描述,但是看下面的範例,應該會很容易瞭解.
 
string a = &quot;Happy birthday, Joel&quot;; // Happy birthday, Joel
string b = @&quot;Happy birthday, Joel&quot;; // Happy birthday, Joel
string c = &quot;hello \t world&quot;; // hello world
string d = @&quot;hello \t world&quot;; // hello \t world
string e = &quot;Joe said &quot;Hello&quot; to me&quot;; // Joe said &quot;Hello&quot; to me
string f = @&quot;Joe said &quot;&quot;Hello&quot;&quot; to me&quot;; // Joe said &quot;Hello&quot; to me
string g = &quot;\\\\server\\share\\file.txt&quot;; // \\server\share\file.txt
string h = @&quot;\\server\share\file.txt&quot;; // \\server\share\file.txt
string i = &quot;one\r\ntwo\r\nthree&quot;;
string j = @&quot;one
two
three&quot;;
 </description>
		<link>http://blog.roodo.com/thinkingmore/archives/554310.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 06 Sep 2005 17:01:26 +0800</pubDate>
					</item>
	<item>
		<title>mod_aspdotnet / Thinking more...</title>
		<description>久久沒去 Apache 網站,想不到 HTTP server 專案下多了一個子專案:  cli(.NET) .
簡單的說,他就是把 Request 都轉成 ASP.Net 可以接的 WebRequest, 然後再讓 ASP.Net application 去處理. 太神奇了,你可以就這麼讓  Apache  把 IIS 替代掉...
目前只支援 Win32 平台上的 .Net 1.0 / 1.1 / 2.0, 而不支援 rotor,  mono ...
這裡有他的 Introduction ...
早知道就不把家裡的 IIS 裝起來了,嗚嗚嗚...</description>
		<link>http://blog.roodo.com/thinkingmore/archives/554291.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 17 Aug 2005 10:17:29 +0800</pubDate>
					</item>
	<item>
		<title>Warning when new web solution / Thinking more...</title>
		<description>之前安裝 Visual Studio.Net 的時候,沒照步驟來,裝完 Visual Studio.Net 之後,才去安裝 IIS.
這樣當然,Visual Studio.Net 還是可以用,但是在新增 Web solution 的時候,老是會出現這個錯誤訊息.
 The class file &#039;WebForm1.aspx.cs&#039; specified as the codebehind for &#039;WebForm1.aspx&#039; could not be loaded.
Make sure that the codebehind attribute in the page or control directive properly references an existing code behind file.
 

網路上可以找到不少關於此問題的描述,但是卻沒有 solution.
找了好久好久,終於找到方法了...

請參考這篇討論: VS.Net Architect - no editor available for aspx files 
簡單的說,就是移除掉 Visual Studio.Net,.Net framework以及必要的 registry 與殘存的檔案,再重新安裝.
 1. HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\7.0
2. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.0
3. HKEY_Local_Machine\Software\Microsoft\.NetFramework
4. HKEY_Local_Machine\Software\Microsoft\Net Framework Setup 
5. The installation directory for VS.NET.
6. .\Documents and Settings\[USERNAME]\Local Settings\Application Data\Microsoft\VisualStudio
7. .\Documents and Settings\[USERNAME]\Application Data\Microsoft\VisualStudio
8. c:\program files\microsoft visual studio .Net
9. C:\windows or winnt\Microsoft.Net
Search for and delete all instances of mscoree.dll 
 
但我只有移除掉 Visual Studio.Net,然後移除掉必要的 registry 與殘存的檔案,.
 1. HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\7.0
2. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.0
3. The installation directory for VS.NET.
4. .\Documents and Settings\[USERNAME]\Local Settings\Application Data\Microsoft\VisualStudio
5. .\Documents and Settings\[USERNAME]\Application Data\Microsoft\VisualStudio
6. c:\program files\microsoft visual studio .Net
 
重新安裝之後就 ok 啦~

真的是花了不少功夫.

When I installed Visual Studio.Net, I don&#039;t follow the correct instrution.  I installed IIS after Visual Studio.Net installation.
Of course, Visual Studio.Net still worked, but there are some messages when you try to new a web solution:
 The class file &#039;WebForm1.aspx.cs&#039; specified as the codebehind for &#039;WebForm1.aspx&#039; could not be loaded.
Make sure that the codebehind attribute in the page or control directive properly references an existing code behind file.
 

You can find some articles about this question, but no articles provide real solutions.
I spend lots of time, finally I got the solution.

Please refer this discussion: VS.Net Architect - no editor available for aspx files 
I try to summary the conclution below:
1. Remove visual studio.net and .Net framework.
2. Remove necessary registry and unremoved files.
 1. HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\7.0
2. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.0
3. HKEY_Local_Machine\Software\Microsoft\.NetFramework
4. HKEY_Local_Machine\Software\Microsoft\Net Framework Setup 
5. The installation directory for VS.NET.
6. .\Documents and Settings\[USERNAME]\Local Settings\Application Data\Microsoft\VisualStudio
7. .\Documents and Settings\[USERNAME]\Application Data\Microsoft\VisualStudio
8. c:\program files\microsoft visual studio .Net
9. C:\windows or winnt\Microsoft.Net
Search for and delete all instances of mscoree.dll 
 
3. Reinstall.

But I only do these steps:
1. Remove Visual Studio.Net.
2. Remove necessary registry and unremoved files.
 1. HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\7.0
2. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.0
3. The installation directory for VS.NET.
4. .\Documents and Settings\[USERNAME]\Local Settings\Application Data\Microsoft\VisualStudio
5. .\Documents and Settings\[USERNAME]\Application Data\Microsoft\VisualStudio
6. c:\program files\microsoft visual studio .Net
 
3. Reinstall.

And everything seems fine now. :)</description>
		<link>http://blog.roodo.com/thinkingmore/archives/554283.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 01 Aug 2005 16:53:32 +0800</pubDate>
					</item>
	<item>
		<title>dotLucene(3) / Thinking more...</title>
		<description>為了要測知添加/刪除的效能,稍微寫了一些程式來測試.
結果還算令人滿意.
添加與刪除每種各測 10 次.
平均起來,添加只花了約一秒左右.
而刪除只花了約 0.015 秒.
算是很快的了.
測試的程序我想就不用貼上來了.

這一陣子也發現了不錯的系列文章
順便一併貼上來. dotLucene 系列文章    dotLucene 系列一 --- 一个小例子    dotLucene 系列二 --- index 上    dotLucene 系列三 --- index 中    dotLucene 系列四 --- index 下     dotLucene 系列五 --- search 上    dotLucene 系列五 --- search 下    </description>
		<link>http://blog.roodo.com/thinkingmore/archives/554275.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 22 Jul 2005 23:03:18 +0800</pubDate>
					</item>
	<item>
		<title>DataSet and xml / Thinking more...</title>
		<description>Export DataSet to XML 的方法:
 	StreamWriter xmlSW = new StreamWriter(&quot;test.xml&quot;, false, Encoding.Default );
	ds.WriteXml(xmlSW, XmlWriteMode.WriteSchema);
	xmlSW.Close();
 

第一行很重要,你得指定 encoding, 否則如果資料編碼不對,xml裡面的字就會顯示不出來.
所以如果你的當地編碼是 big5, 而且你的資料庫資料的編碼也是 big5, 那麼你應該使用 Encoding.Default. 

Import DataSet from XML 的方法:
 	StreamReader xmlSR = new StreamReader( fileName, Encoding.Default ); 
	ds.ReadXml( xmlSR, XmlReadMode.ReadSchema );
	xmlSR.Close();
 

同理可證,你怎麼寫出去,就怎麼讀回來,這樣資料的編碼才不會有問題...

這我試了快兩個小時... =_=&quot;
居然沒發現到 Encoding 有個 Default 的屬性,害我用 Encoding.ASCII 在那邊試半天...</description>
		<link>http://blog.roodo.com/thinkingmore/archives/554273.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 19 Jul 2005 17:24:08 +0800</pubDate>
					</item>
	<item>
		<title>UI/worker thread / Thinking more...</title>
		<description>為了要解決進度顯示的問題,上 MSDN 找了一下,果然得到圓滿答覆.
請直接參考這幾篇吧...
   Safe, Simple Multithreading in Windows Forms, Part 1    Safe, Simple Multithreading in Windows Forms, Part 2    Safe, Simple Multithreading in Windows Forms, Part 3    Give Your .NET-based Application a Fast and Responsive UI with Multiple Threads   

簡單說明一下,主要是應用 .Net framework 本身就提供的架構,呼叫 Control 的 BeginInvoke() 去調用自己的 delegate 來幫你畫 UI, 以避免因為訊息繁忙而來不及更新畫面的問題.
如果要讓它可以被 cancel, 那麼,可以再配合 Event 來達到這個目的.

Cancel 的部份,我後來沒有用 Event 來做,這是我比較偷懶的地方.

對這方面如果還需要更詳細的了解,可以參考 侯捷 的Win32多緒程式設計.
不過這本書好像絕版了?!</description>
		<link>http://blog.roodo.com/thinkingmore/archives/554271.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 14 Jul 2005 14:37:24 +0800</pubDate>
					</item>
	<item>
		<title>dotLucene(2) / Thinking more...</title>
		<description>其實,依照  dotLucene  網站所提供的  Tutorial ,就已經蠻足夠的了.不過我還是同時參考了源碼裡所附的 Demo. 
 
這邊我就只寫出跟 Tutorial / Demo 不同的地方... 
  在 Document 部分,我參考了 Demo 的寫法, 另外寫了一個 FileDocument, 來產生 IndexWriter 所需要的 Document 類別.
 	public class FileDocument
	{
		public static Document Document( string title, string content)
		{
			// make a new, empty document
			Document doc = new Document();
			
			// Add necessary fields
			// 這邊要 tokenized, 為了中文...
			doc.Add( new Field(&quot;title&quot;, title, Field.Store.YES, Field.Index.TOKENIZED));
			
			// Add the contents of the file to a field named &quot;contents&quot;.
			// 原來是用 stream reader 來把整個檔案內容讀進來
			// 這邊改成只把欄位資料放進去.
			doc.Add( new Field(&quot;contents&quot;, content, Field.Store.YES, Field.Index.TOKENIZED));
			
			// return the document
			return doc;
		}
		
		private FileDocument()
		{
		}
   我把原來的 QueryParser 改成 MultiFieldQueryParser, 因為我想同時搜索主旨與內容.
 			string[] fields = { &quot;title&quot;, &quot;contents&quot; };
			Query query = MultiFieldQueryParser.Parse( txtQueryString.Text, fields, analyzer );
			Hits hits = searcher.Search(query);
   
 
大致上就這樣子... 
我之後想搞一個進度顯示,讓使用者不會覺得太慢,不過怎麼樣都不行. 
這應該就要應用所謂的 UI/worker thread 的技術了吧... 
真的是對 Windows form.Net 太不熟了... 
這再慢慢摸索吧... </description>
		<link>http://blog.roodo.com/thinkingmore/archives/554270.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 11 Jul 2005 22:32:54 +0800</pubDate>
					</item>
	<item>
		<title>dotLucene(1) / Thinking more...</title>
		<description>上星期逛網路的時候,不小心讓我給逛到 Lucene
   Lucene：基于Java的全文检索引擎简介    DotLucene:37行代码实现全文搜索    DotLucene: Full-Text Search for Your Intranet or Website using 37 Lines of Code   

雖然以前就大略知道 Lucene, 但卻搞不太清楚他是幹麼的,逛完這幾篇之後,才知道是幹麼的.
於是就很想應用在 紅狐論壇 上.

上面的文章都是很不錯的入門文章,但是在我一開始投入的時候,的確讓我有很多困擾:  例子多半都是用 File / Directory 當作範例,真的可以用來搜索資料庫嗎?  又資料庫本身就有不錯的全文檢索,那麼,還需要這個嗎??   DotLuceneFbDirectory: DotLucene Index Storage for Firebird  這篇文章說可以拿  Firebird  database 當作 storage, 那麼,我需要參考這篇文章這麼作嗎??  

想了兩三天,也仔細看了兩三天...
  的確可以,  dotLucene  有提供 Document 類別,而此類別可以讓你自由添加 Field 進去,所以我可以直接添加 Table 裡的某些欄位進去. 在 asp.net 上應用時,我可以參考這些我自定的欄位來產生網址,讓使用者可以直接點選網址進入.  像 Microsoft SQL server 的確有提供全文檢索功能,可是據說很費效能. dotLucene 還不錯,搜索的時候速度蠻快的,也沒花什麼資源(用工作管理員觀察),不過這部分還需要詳細的實驗才知道.  仔細看完這篇 文章 以後,才發現,雖然可以利用 database 當作 storage,可是並不建議,因為效能不高. 可惜的是文章內容並沒有提供效能評比,無法作進一步的比較.  

在整個考量以後,決定先以 紅狐 所提供的論壇資料作為一個練習,也可以順便作一些實驗.</description>
		<link>http://blog.roodo.com/thinkingmore/archives/554269.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Mon, 11 Jul 2005 21:31:53 +0800</pubDate>
					</item>
	<item>
		<title>mod_mono_server init script / Thinking more...</title>
		<description>為了要讓 mod_mono_server 能在開機時自動啟動,就得自行撰寫 script.
自己嘗試了幾次,總是不如己意.大概是自己的 bash script 功力不到家吧~

只能利用 Google 大神去搜尋別人的成果.
很幸運,已經有人寫出來了.有好幾種版本:
1. mono-server.init, 這個 script 相當不錯,已經可以讓你在配置檔(/etc/xsp/mono-xsp-hosts.conf)裡面設定 host 了.同時也已經收錄,作為 Debian 官方 xsp 套件的一部分.
2. local-xsp, 這個 script 也是 for Debian 的,但沒辦法設定 host.
3. mod_mono, 我是在 這兒 找到的,這個可以在 fedora/red hat 裡面用,沒問題.

我最後是用了 3 的 solution,並加上了一些修改,不過你應該看的出來,更動並不大就是了 :)
 
#!/bin/sh
#
# chkconfig: 2345 99 01
# description: Provides ASP.NET functionality for Apache
# mod_mono Start the mod_mono-server
#

NAME=aspnet
MONOPIDFILE=/var/run/aspnet.pid

export MONO_PATH=/usr/lib/mono/1.0/

start_mod_mono() {
        tmp=`ps ax | grep -m 1 &quot;/usr/bin/mono&quot;`
        tmp=`echo $tmp | grep &quot;/usr/bin/mod-mono-server.exe&quot; | awk &#039;{print $1}&#039;`
        if [ $tmp ]; then
                echo -n &quot;$NAME already started&quot;
        else
                echo &quot;Starting server $NAME&quot;
                #/usr/bin/mono /usr/bin/mod-mono-server.exe --root /usr/local/share/doc/xsp/test/ --applications /mono:. --nonstop &amp;
                #/usr/bin/mono /usr/bin/mod-mono-server.exe --root /var/www/html/mono/ --applications /mono:. --nonstop &amp;
                /usr/bin/mono /usr/bin/mod-mono-server.exe --root /usr/share/doc/xsp-0.9/xsp/test --applications /mono:. --nonstop &amp;
                sleep 3
                chmod 666 /tmp/mod_mono_server
        fi
}
stop_mod_mono() {
        # (MO): Asking for an existing process for the mod-mono-server
        # (MO): Abfragen, ob es eine Prozeß für mod-mono-server schon gibt.
        tmp=`ps ax | grep -m 1 &quot;/usr/bin/mono&quot;`
        tmp=`echo $tmp | grep &quot;/usr/bin/mod-mono-server.exe&quot; | awk &#039;{print $1}&#039;`
        if [ $tmp ]; then
   echo -n &quot;Stopping mod_mono&quot;
                tmp=`ps ax | grep &quot;/usr/bin/mono&quot; | grep &quot;/usr/bin/mod-mono-server.exe&quot; | awk &#039;{print $1}&#039;`
                kill -9 $tmp
        else
                echo -n &quot;$NAME is not started&quot;
        fi
}
case &quot;$1&quot; in
 start)
                start_mod_mono
   ;;

 stop)
                stop_mod_mono
                echo
   ;;

 restart)
   echo &quot;Restarting $NAME&quot;
                stop_mod_mono
                echo
                sleep 1
                start_mod_mono
   ;;

        status)
                tmp=`ps ax | grep -m 1 &quot;/usr/bin/mono&quot;`
                tmp=`echo $tmp | grep &quot;/usr/bin/mod-mono-server.exe&quot; | awk &#039;{print $1}&#039;`
                if [ $tmp ]; then
                        echo &quot;$NAME is running&quot;;
                else
                        echo &quot;$NAME is not runnung&quot;;
                fi
                ;;

 *)
   echo &quot;Usage: /etc/init.d/$NAME {start|stop|restart|status}&quot;
   exit 1
   ;;
esac

if [ $? -eq 0 ]; then
        #echo
        exit 0
else
        echo &quot; failed&quot;
        exit 1
fi
 </description>
		<link>http://blog.roodo.com/thinkingmore/archives/554236.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Fri, 18 Mar 2005 23:36:55 +0800</pubDate>
					</item>
	<item>
		<title>cannot handle TLS data / Thinking more...</title>
		<description>最近更新了 dag 的 mono RPM 以後,mono 只會說
 mono: error while loading shared libraries: libmono.so.0: cannot handle TLS data 

令人無奈...去抓 官方網站  的 RPM for rh9(因為我用的是 WBEL ,不能用 Fedore Core 3 的 rpm)之後,也無法使用...

在網路上搜尋了一下,其實所謂的 TLS 有兩種: Transport Layer Security, 或是 Thread-Local Storage.  一開始我被搞混了,我以為是 Transport Layer Security, 所以我更新了 openssl 等等相關的 library, 但是卻於事無補.

後來又多花了一天在找這問題,終於,我才發現是 Thread-Local Storage 搞的.可惡,我心裡想,這個我不搞清楚,那我這兩三年的 Linux 經驗豈不是白混的??又繼續找,看到底是缺了什麼 library,才會這樣...今天我終於找到解答,原因是因為我的 glibc 是 i386 arch 的,並沒包含 tls 的部分,所以必須要更新到 i586/i686 才可以.

對,我承認我膽小,所以我不敢強制把我的 glibc 升到 i586 (我的 linux 是架設在 AMD 350 上...,所以是 i586),於是我退而求其次,我重新下載 DAG 網站上的 mono.spec, 把 revision 改為 2, 重新包裝 source rpm, 然後再編譯一次.這次,當然就可以安裝了~~

嗚嗚嗚~~真是花了我不少功夫啊....

註:
Thread-Local Storage
 http://linux.web.cern.ch/linux/scientific3/docs/rhel-gcc-en-3/thread-local.html </description>
		<link>http://blog.roodo.com/thinkingmore/archives/554232.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 15 Mar 2005 22:38:37 +0800</pubDate>
					</item>
	<item>
		<title>NAnt 與 mono / Thinking more...</title>
		<description>既然已經可以使用 mono 了，於是我也想在 mono 下使用  NAnt 。

幸運的是，NAnt 已經支援 mono 了。所以只要下載解開以後，執行 make 即可。如果你的 mono 是 1.0.6 而你用的 NAnt 又是最新版的 0.85-rc2，那麼我相信你應該會遇到問題。這個時候你應該到  mono 官方網站  下載 unstable 的 1.1.4，雖說是 unstable，但依據網站上的說明，其實這一版已經相當穩定也整合了更多的東西進來。

下載並安裝之後，應該就可以編譯 NAnt 了。

如果你想用 NAnt 的 rpm 來安裝，也是可以，請先到 這裡 下載 nant.spec，然後打開 nant.spec，將這幾行刪掉：
 Patch0:		%{name}-xml_syntax.patch
Patch1:		%{name}-PlatformID.patch
%patch0 -p1
%patch1 -p1
 
因為在最新的 NAnt 的 source 已經 patch 了。

接著把 nant 的 tarball 放到 /usr/src/redhat/SOURCES/，執行
 #rpmbuild -bs nant.spec
#rpmbuild --rebuild /usr/src/redhat/SRPMS/nant-0.85-0.rc2.1.src.rpm 
就可以在 /usr/src/redhat/RPMS/i386 下找到剛 build 完的 nant rpm 了。</description>
		<link>http://blog.roodo.com/thinkingmore/archives/554228.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Wed, 09 Mar 2005 12:56:44 +0800</pubDate>
					</item>
	<item>
		<title>mono xsp / Thinking more...</title>
		<description>今天搞了一天...把心得記述一下...
其實安裝步驟很簡單:
1.因為我是用 rpm base 的  WhiteBox Enterprise Linux ,所以先到  DAG:Apt/Yum RPM repository 去安裝 mono / xsp / mod_mono 套件.懶得自己挑的話,就用 mono-complete / xsp / mod_mono.
2.到了這裡,其實已經裝好一半. 設定 MONO_PATH
 
export MONO_PATH=/usr/lib/mono/1.0/
 
3.在 /etc/httpd/conf.d/ 下,新增一個 mono.conf, 內容如下:
 
AddType application/x-asp-net .aspx .ashx .asmx .ascx .asax .config .ascx
LoadModule mono_module modules/mod_mono.so
MonoUnixSocket /tmp/mod_mono_server
Alias /mono &quot;/usr/share/doc/xsp-0.9/xsp/test/&quot;
&amp;lt;Directory &quot;/usr/share/doc/xsp-0.9/xsp/test&quot;&amp;gt;
    Options Indexes FollowSymLinks
    AllowOverride FileInfo
    Order allow,deny
    Allow from all
    AddHandler mono .aspx .ascx .asax .ashx .config .cs .asmx
&amp;lt;/Directory&amp;gt;
DirectoryIndex index.aspx Default.aspx
 

4.重新啟動 httpd
5.修改 /usr/share/doc/xsp-0.9/xsp/test/mod-mono-server.exe.config, 找到 MonoApplications, 將 value 改為 /mono:.
6.切換到 /usr/share/doc/xsp-0.9/xsp/test 下,執行:
 
#mono /usr/bin/mod-mono-server.exe --root . --applications /mono:.
 
7. 將 /tmp/mod_mono_server 的 owner 改為 apache :
 
#chown apache:apache /tmp/mod_mono_server
 

大功告成,接著你可以利用瀏覽器輸入 http://your_server/mono/ 來看結果了...

這邊其實 apache 的 mod_mono module 是利用 Unix Socket 與 mod-mono-server 溝通的,所以並不會去 listen 任何一個 port...
我之前以為他會與 xsp 一樣,會 listen 8080 port, 猜錯 @_@</description>
		<link>http://blog.roodo.com/thinkingmore/archives/554216.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Sat, 12 Feb 2005 22:07:16 +0800</pubDate>
					</item>
	<item>
		<title>asp.net 的 deploy / Thinking more...</title>
		<description>deploy asp.net program 的時候,如果用 copy 的話,可以這樣用~
 XCOPY \\CLIENT1\wwwroot\demowebsrv \\SERVER1\wwwroot\demowebsrv /E /K /R /O /H /I 
快又方便.</description>
		<link>http://blog.roodo.com/thinkingmore/archives/554123.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 16 Sep 2004 17:37:55 +0800</pubDate>
					</item>
	<item>
		<title>為 DataGrid 加入 Checkbox / Thinking more...</title>
		<description>大致就是這樣啦,在 ItemDataBound event 加這個進去就行了~~ 
主要用在 asp.net 上... 
 
 private void DataGrid1_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
{
&amp;nbsp;&amp;nbsp;CheckBox cb=new CheckBox();
&amp;nbsp;&amp;nbsp;if(e.Item.ItemIndex&gt;=0)
&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(e.Item.Cells[2].Text==&quot;True&quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cb.Checked=true;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cb.Checked=false;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e.Item.Cells[2].Controls.Clear();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e.Item.Cells[2].Controls.Add(cb);
&amp;nbsp;&amp;nbsp;}
} </description>
		<link>http://blog.roodo.com/thinkingmore/archives/554122.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 16 Sep 2004 14:09:21 +0800</pubDate>
					</item>
	<item>
		<title>MDI Form / Thinking more...</title>
		<description>總之作法大致就是這樣
把 Form 的 property 設一下, Menu 裡面的 Item click event 就是這麼寫...

 
Private Sub MenuItem3_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles MenuItem3.Click 
&amp;nbsp;&amp;nbsp;Dim frm As Form3 = New Form3 
&amp;nbsp;&amp;nbsp;If check(frm) Then Return 
&amp;nbsp;&amp;nbsp;frm.MdiParent = Me 
&amp;nbsp;&amp;nbsp;frm.Show() 
End Sub 
 
Private Function CeckExist(ByVal compareFrom As Form) As Boolean 
&amp;nbsp;&amp;nbsp;For Each f As Form In Me.MdiChildren 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If f.GetType().Equals(compareFrom.GetType()) Then 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f.BringToFront() &#039; f.Focus() 也可以 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Return True 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End If 
&amp;nbsp;&amp;nbsp;Next 
&amp;nbsp;&amp;nbsp;Return False 
End Function
 </description>
		<link>http://blog.roodo.com/thinkingmore/archives/554121.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Thu, 16 Sep 2004 14:05:34 +0800</pubDate>
					</item>
	<item>
		<title>Defrag API C# wrappers / Thinking more...</title>
		<description>在  http://blogs.msdn.com  發現了 這篇 , 想不到居然可以把磁碟重組的 API 包起來用...
這可真是有趣.
搞不好也可以搞一個自己的重組程式喔~~呵呵~~
p.s. 我以前真的不知道 Win32 API 有包括磁碟重組的部份... &gt;_&lt;</description>
		<link>http://blog.roodo.com/thinkingmore/archives/554117.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 14 Sep 2004 19:56:41 +0800</pubDate>
					</item>
	<item>
		<title>c# using / Thinking more...</title>
		<description> http://www.codeproject.com/csharp/TinguUsingStatement.asp 
using 是一個可以確保物件會被 dispose 的 syntax,
當使用
 
using( aaa a=new aaa() )
{
  a.doSomething();
}
 
實際上就等於是
 
aaa a=new aaa();
try
{
  a.doSomething();
}
finally
{
  if( a!=null )
    ((IDisposable)a).Dispose();
}
 </description>
		<link>http://blog.roodo.com/thinkingmore/archives/554116.html</link>
		<author>info@blog.roodo.com&lt;info@blog.roodo.com&gt;</author>
		<category>網路/3C</category>
		<pubDate>Tue, 14 Sep 2004 13:49:09 +0800</pubDate>
					</item>
</channel>
</rss>