<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" 
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Thinking more...-.Net</title>
<link>http://blog.roodo.com/thinkingmore/archives/cat_82805.html</link>
<description>Just thinking more...&amp;nbsp;訂閱 RSS

var gaJsHost = ((&quot;https:&quot; == document.location.protocol) ? &quot;https://ssl.&quot; : &quot;http://www.&quot;);
document.write(unescape(&quot;%3Cscript src=&#039;&quot; + gaJsHost + &quot;google-analytics.com/ga.js&#039; type=&#039;text/javascript&#039;%3E%3C/script%3E&quot;));















  google.load(&quot;jquery&quot;, &quot;1.2&quot;);
  google.setOnLoadCallback( function() {
    try {
      var pageTracker = _gat._getTracker(&quot;UA-97150-7&quot;);
      pageTracker._trackPageview();
    }catch(err) {}
    $(&quot;pre &gt; br&quot;).each( function() { $(this).replaceWith( &quot;\n&quot; ); } );
    $(&quot;textarea &gt; br&quot;).each( function() { $(this).replaceWith( &quot;\n&quot; ); } );
    SyntaxHighlighter.config.ClipboardSwf = &#039;http://alexgorbatchev.com/pub/sh/2.0.296/scripts/clipboard.swf&#039;;
    SyntaxHighlighter.all();
    dp.SyntaxHighlighter.ClipboardSwf = &#039;http://alexgorbatchev.com/pub/sh/2.0.296/scripts/clipboard.swf&#039;;
    dp.SyntaxHighlighter.HighlightAll(&#039;code&#039;);
  } );

</description>
<language>zh-tw</language>
<generator>Roodo Blog System</generator>
<copyright>All Rights Reserved</copyright>
<atom:link href="http://blog.roodo.com/thinkingmore/archives/cat_82805.xml" rel="self" type="application/rss+xml" />
<item>
	<title>Upgrade Mono to 2.4.2.3 in Ubuntu Jaunty</title>
	<description><![CDATA[
			網路上能看到的，多半都是自己編譯 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 && dpkg-scanpackages . /dev/null | gzip -9c &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>
	<content:encoded><![CDATA[
			網路上能看到的，多半都是自己編譯 tarball...<br />
<br />
<ol><li>下載 <a href="http://packages.ubuntu.com/source/karmic/mono">mono in karmic</a> 頁面 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 加上可執行的屬性。</li><li>安裝必要的套件: 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</li><li>打開 debian/shlibs.local，把 libsqlite3 後面的  3.6.13 改為 3.6.10，因為 9.04 的 sqlite 是 3.6.10 版。</li><li>切到 mono 下，開始 build: cd mono;dpkg-buildpackage</li><li>把打包好的 deb 作成 local repository: 假設你把這些 deb 都放到 /opt/mono_debs 下，然後建立 Packages.gz: cd /opt/mono_debs && dpkg-scanpackages . /dev/null | gzip -9c &gt; Packages.gz。</li><li>新增 apt repository:在 /etc/apt/sources.list.d/ 下新增一個 mono.list，裡面放: <pre>deb file:///opt/mono_debs ./</pre>接下來就可以用 apt-get update、apt-get upgrade 來更新了。</li></ol><br />
<br />
理論上，這樣就可以更新了，但是事實上，因為 dependency 的關係，apt 會試圖安裝舊的 2.0.1 的 deb 來滿足相依性而導致應用程式有問題。<br />
最好，也循上述的方法，把相關的基底 gtk-sharp2、xsp、gecko-sharp、mono-addins...等套件也重新 build 一次，這樣出現問題的情況應該會減少許多。<br />
<br />
我個人建議，要用最新的 mono 還是衝 Karmic (9.10) 吧，這樣會省事很多。<br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/9976249.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/9976249.html</guid>
	<category>.Net</category>
	<pubDate>Thu, 17 Sep 2009 14:54:39 +0800</pubDate>
</item>
<item>
	<title>WebDev.WebServer.exe</title>
	<description><![CDATA[
			朋友傳給我幾個 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，裡面有這麼幾行：
&lt;system.web&gt;
&lt;assemblies&gt;
	&lt;add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/&gt;
	&lt;add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/&gt;
	&lt;add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/&gt;
	&lt;add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/&gt;
&lt;/assemblies&gt;
&lt;/system.web&gt;

一切真相大白，原來是補上了 3.0/3.5 所需的 Assembly，讓 WebDev.WebServer.exe 在跑 3.0/3.5 的 ASP.Net 網頁時沒有問題。

		]]>
	</description>
	<content:encoded><![CDATA[
			朋友傳給我幾個 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，裡面有這麼幾行：<pre name="code" class="xml">
&lt;system.web&gt;
&lt;assemblies&gt;
	&lt;add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/&gt;
	&lt;add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/&gt;
	&lt;add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/&gt;
	&lt;add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/&gt;
&lt;/assemblies&gt;
&lt;/system.web&gt;
</pre>
一切真相大白，原來是補上了 3.0/3.5 所需的 Assembly，讓 WebDev.WebServer.exe 在跑 3.0/3.5 的 ASP.Net 網頁時沒有問題。

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/9536021.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/9536021.html</guid>
	<category>.Net</category>
	<pubDate>Mon, 27 Jul 2009 17:13:59 +0800</pubDate>
</item>
<item>
	<title>Mono rpms for CentOS/RHEL 4.x</title>
	<description><![CDATA[
			雖然Mono官方不再提供 CentOS/RHEL 4.x 的 rpm 了，你還是可以自己重新 build。
在我看過 spec 檔案以後，我發現 Mono 開發團隊已經有加上對 Linux 發行套件的判斷，也就是說其實你可以直接下載 source rpm，安裝必要的函式庫之後，執行 rpmbuild --rebuild xxx.src.rpm 來 build 出 rpm。

source rpms 放在 這裡。

		]]>
	</description>
	<content:encoded><![CDATA[
			雖然<a href="http://www.go-mono.com/mono-downloads/download.html">Mono官方</a>不再提供 CentOS/RHEL 4.x 的 rpm 了，你還是可以自己重新 build。<br />
在我看過 spec 檔案以後，我發現 Mono 開發團隊已經有加上對 Linux 發行套件的判斷，也就是說其實你可以直接下載 source rpm，安裝必要的函式庫之後，執行 rpmbuild --rebuild xxx.src.rpm 來 build 出 rpm。<br />
<br />
source rpms 放在 <a href="http://ftp.novell.com/pub/mono/download-stable/openSUSE_11.1/src/">這裡</a>。<br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/9082763.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/9082763.html</guid>
	<category>.Net</category>
	<pubDate>Wed, 27 May 2009 23:50:35 +0800</pubDate>
</item>
<item>
	<title>如何在 .Net 調用Yahoo!搜索 斷章取義 API</title>
	<description><![CDATA[
			無心工作，剛好又看到有人問怎麼用，所以就牛刀小試一下。基本上用 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("localhost", 8000);
            client.Encoding = Encoding.UTF8;
            return client;
        }

        private NameValueCollection GetParameters()
        {
            NameValueCollection data = new NameValueCollection();

            // TODO: Place your appid here.
            data.Add("appid", "APgdNPnV34E7WQlhpBYaQvaRWPjwvd8exe094Q_r_7GWEOBFh9UDQY6vqNgZVwhc");
            return data;
        }

        public string WordSegmentation(string content)
        {
            NameValueCollection data = GetParameters();
            data.Add("content", content);

            WebClient client = GetWebClient();
            byte[] responseArray = client.UploadValues("http://asia.search.yahooapis.com/cas/v1/ws", "POST", data);
            return _GetString(responseArray);
        }

        public string Authenticate()
        {
            NameValueCollection data = GetParameters();

            WebClient client = GetWebClient();
            byte[] responseArray = client.UploadValues("http://asia.search.yahooapis.com/cas/v1/AuthBootUp.php", "POST", data);
            return _GetString(responseArray);
        }

        public string KeywordExtraction( string content, int threshold, int maxnum )
        {
            NameValueCollection data = GetParameters();
            data.Add("content", content);
            data.Add("threshold", threshold.ToString());
            data.Add("maxnum", maxnum.ToString());

            WebClient client = GetWebClient();
            byte[] responseArray = client.UploadValues("http://asia.search.yahooapis.com/cas/v1/ke", "POST", data);
            return _GetString(responseArray);
        }

        public static void Main() 
        {
            Yahoo.CAS cas = new Yahoo.CAS();

            // 如果你重新申請 appid 的話，要先作 Authenticate
            // Console.WriteLine( cas.Authenticate() );
            Console.WriteLine( cas.WordSegmentation( "your_text" ));
            Console.WriteLine( cas.KeywordExtraction( "your_text", 30, 10));

            // 得到的字串是 XML，要轉為 DataSet 的話，可以這樣作
            /*
            string text = cas.WordSegmentation( "your_text" );
            TextReader stringReader = new StringReader(text);
            DataSet dataSet1 = new DataSet();
            dataSet1.ReadXml(stringReader);
            // 轉好以後應會有兩個 DataTable，資料都在第二個 Table 裡，也就是 dataSet1.Tables[1]
            */
        }
    }
}


		]]>
	</description>
	<content:encoded><![CDATA[
			無心工作，剛好又看到有人問怎麼用，所以就牛刀小試一下。基本上用 WebClient 就可以搞定：

<pre name="code" class="c#">
//
// 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("localhost", 8000);
            client.Encoding = Encoding.UTF8;
            return client;
        }

        private NameValueCollection GetParameters()
        {
            NameValueCollection data = new NameValueCollection();

            // TODO: Place your appid here.
            data.Add("appid", "APgdNPnV34E7WQlhpBYaQvaRWPjwvd8exe094Q_r_7GWEOBFh9UDQY6vqNgZVwhc");
            return data;
        }

        public string WordSegmentation(string content)
        {
            NameValueCollection data = GetParameters();
            data.Add("content", content);

            WebClient client = GetWebClient();
            byte[] responseArray = client.UploadValues("http://asia.search.yahooapis.com/cas/v1/ws", "POST", data);
            return _GetString(responseArray);
        }

        public string Authenticate()
        {
            NameValueCollection data = GetParameters();

            WebClient client = GetWebClient();
            byte[] responseArray = client.UploadValues("http://asia.search.yahooapis.com/cas/v1/AuthBootUp.php", "POST", data);
            return _GetString(responseArray);
        }

        public string KeywordExtraction( string content, int threshold, int maxnum )
        {
            NameValueCollection data = GetParameters();
            data.Add("content", content);
            data.Add("threshold", threshold.ToString());
            data.Add("maxnum", maxnum.ToString());

            WebClient client = GetWebClient();
            byte[] responseArray = client.UploadValues("http://asia.search.yahooapis.com/cas/v1/ke", "POST", data);
            return _GetString(responseArray);
        }

        public static void Main() 
        {
            Yahoo.CAS cas = new Yahoo.CAS();

            // 如果你重新申請 appid 的話，要先作 Authenticate
            // Console.WriteLine( cas.Authenticate() );
            Console.WriteLine( cas.WordSegmentation( "your_text" ));
            Console.WriteLine( cas.KeywordExtraction( "your_text", 30, 10));

            // 得到的字串是 XML，要轉為 DataSet 的話，可以這樣作
            /*
            string text = cas.WordSegmentation( "your_text" );
            TextReader stringReader = new StringReader(text);
            DataSet dataSet1 = new DataSet();
            dataSet1.ReadXml(stringReader);
            // 轉好以後應會有兩個 DataTable，資料都在第二個 Table 裡，也就是 dataSet1.Tables[1]
            */
        }
    }
}
</pre>

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/8932571.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/8932571.html</guid>
	<category>.Net</category>
	<pubDate>Wed, 13 May 2009 13:37:49 +0800</pubDate>
</item>
<item>
	<title>列出 log4net 設定裡所有的 repository 跟 appender</title>
	<description><![CDATA[
			Debug 用的，主要是看自己的 log4net 設定對不對。


StringBuilder sb = new StringBuilder();
ILoggerRepository[] repos = LogManager.GetAllRepositories();
foreach( ILoggerRepository repo in repos )
{
	sb.AppendLine( "=====" );
	sb.AppendLine( string.Format( "{0} - configured={1}", repo.Name, repo.Configured.ToString() );
	sb.AppendLine( "Appenders:" );
	foreach( IAppender appender in repo.GetAppenders() )
	{
		sb.AppendLine( string.Format( "\t{0}", appender.Name ) );
	}
}
sb.AppendLine( "=====" );
Console.WriteLine( sb.ToString() );


		]]>
	</description>
	<content:encoded><![CDATA[
			Debug 用的，主要是看自己的 log4net 設定對不對。

<pre name="code" class="csharp">
StringBuilder sb = new StringBuilder();
ILoggerRepository[] repos = LogManager.GetAllRepositories();
foreach( ILoggerRepository repo in repos )
{
	sb.AppendLine( "=====" );
	sb.AppendLine( string.Format( "{0} - configured={1}", repo.Name, repo.Configured.ToString() );
	sb.AppendLine( "Appenders:" );
	foreach( IAppender appender in repo.GetAppenders() )
	{
		sb.AppendLine( string.Format( "\t{0}", appender.Name ) );
	}
}
sb.AppendLine( "=====" );
Console.WriteLine( sb.ToString() );
</pre>

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/7119835.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/7119835.html</guid>
	<category>.Net</category>
	<pubDate>Fri, 05 Sep 2008 16:27:20 +0800</pubDate>
</item>
<item>
	<title>debuan/ubuntu nant-0.85 的 SMP bug</title>
	<description><![CDATA[
			最近在 Ubuntu 下用 NAnt 時，有 50% 的機率會遇到類似這樣的錯誤：The current runtime framework 'mono-2.0' is not correctly configured in the NAnt configuration file.
    Function call failed.
Expression: ${path::combine(prefix, 'lib/mono/1.0')}
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        Illegal characters in path
Parameter name: path1


找了好久，都不知道原因所在，因為有時候是正常執行的。去Google試了好幾個關鍵字，都找不到解。今天用 nant "Illegal characters in path" 去找，終於找到了：#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>
	<content:encoded><![CDATA[
			最近在 <a href="http://www.ubuntulinux.com">Ubuntu</a> 下用 <a href="http://nant.sourceforge.net">NAnt</a> 時，有 50% 的機率會遇到類似這樣的錯誤：<pre>The current runtime framework 'mono-2.0' is not correctly configured in the NAnt configuration file.
    Function call failed.
Expression: ${path::combine(prefix, 'lib/mono/1.0')}
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        Illegal characters in path
Parameter name: path1
</pre>

找了好久，都不知道原因所在，因為有時候是正常執行的。去<a href="http://www.google.com">Google</a>試了好幾個關鍵字，都找不到解。今天用 nant "Illegal characters in path" 去找，終於找到了：<a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=483073">#483073 - nant: race condition on SMP systems - Debian Bug report logs</a><br/>
裡面提供的暫時解法是利用環境變數 MONO_NO_SMP，把 SMP 關掉，再執行即可。所以只要編輯 /usr/bin/nant，在 exec 之前加上 export MONO_NO_SMP=1 即可。

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/6978141.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/6978141.html</guid>
	<category>.Net</category>
	<pubDate>Mon, 25 Aug 2008 14:53:25 +0800</pubDate>
</item>
<item>
	<title>最近用 MySql Connector/Net 的幾個心得</title>
	<description><![CDATA[
			連線字串加上 charset=utf8，如此一來，完全不用更改 MySQL 伺服器設定，只要確定建 database/table 時有指定 utf-8 編碼即可。SQL 參數在使用 @ 時，若碰到問題，不妨改用 ? 試試。我的確碰到這問題，它卡了我兩、三天，而且改用 ? 也解決了。忘了在哪兒看到，剛好有提到這點，真的是幸好我有看到...MySQL 有提供 MySqlHelper 類別，省掉寫 Helper 的麻煩...MySQLConnector/Net下載網站上沒有給 Linux 的版本，事實上，是通用的，你可以直接拿給Mono用，不需要作任何改動。

		]]>
	</description>
	<content:encoded><![CDATA[
			<ol><li>連線字串加上 charset=utf8，如此一來，完全不用更改 <a href="http://www.mysql.com/">MySQL</a> 伺服器設定，只要確定建 database/table 時有指定 utf-8 編碼即可。</li><li>SQL 參數在使用 @ 時，若碰到問題，不妨改用 ? 試試。我的確碰到這問題，它卡了我兩、三天，而且改用 ? 也解決了。忘了在哪兒看到，剛好有提到這點，真的是幸好我有看到...</li><li><a href="http://www.mysql.com/">MySQL</a> 有提供 MySqlHelper 類別，省掉寫 Helper 的麻煩...</li><li><a href="http://www.mysql.com/">MySQL</a><a href="http://dev.mysql.com/downloads/connector/net/">Connector/Net下載網站</a>上沒有給 Linux 的版本，事實上，是通用的，你可以直接拿給<a href="http://www.go-mono.com">Mono</a>用，不需要作任何改動。</li></ol><br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/6898775.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/6898775.html</guid>
	<category>.Net</category>
	<pubDate>Fri, 22 Aug 2008 09:51:23 +0800</pubDate>
</item>
<item>
	<title>.NET framework essential Chapter 7/8-ASP.Net/Windows form</title>
	<description><![CDATA[
			各自只有一個章節，不過作者很簡明扼要地把該介紹的東西都介紹了。

ASP.Net 除了講 HtmlControl、WebControl 以外，還介紹了 Directive、Session 設定等等。
Windows form 則是簡單的介紹如何開始、Layout 的配置，以及比較容易讓人混淆的 MDI Form。

這本書真的很不錯，講的都很基本，看完對 .NET 會有一定程度的了解，不至於在茫茫大海似的類別庫裡淹死。

		]]>
	</description>
	<content:encoded><![CDATA[
			各自只有一個章節，不過作者很簡明扼要地把該介紹的東西都介紹了。<br />
<br />
ASP.Net 除了講 HtmlControl、WebControl 以外，還介紹了 Directive、Session 設定等等。<br />
Windows form 則是簡單的介紹如何開始、Layout 的配置，以及比較容易讓人混淆的 MDI Form。<br />
<br />
這本書真的很不錯，講的都很基本，看完對 .NET 會有一定程度的了解，不至於在茫茫大海似的類別庫裡淹死。<br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/6705987.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/6705987.html</guid>
	<category>.Net</category>
	<pubDate>Fri, 08 Aug 2008 09:51:55 +0800</pubDate>
</item>
<item>
	<title>App_Offline.htm</title>
	<description><![CDATA[
			今天 Trace Mono System.Web.HttpRuntime 時看到的，如果在你 ASP.Net 2.0 網站目錄下放置一個 app_offline.htm 時，不管你瀏覽什麼網頁，都只會看到 app_offline.htm 的內容。

詳情可以參考 ScottGu 大 的文章：App_Offline.htm

很鳥的是，.NET Documentation 裡完全沒提到這個。

		]]>
	</description>
	<content:encoded><![CDATA[
			今天 Trace <a href="http://www.mono-project.com">Mono</a> System.Web.HttpRuntime 時看到的，如果在你 ASP.Net 2.0 網站目錄下放置一個 app_offline.htm 時，不管你瀏覽什麼網頁，都只會看到 app_offline.htm 的內容。<br />
<br />
詳情可以參考 <a href="http://weblogs.asp.net/scottgu/default.aspx">ScottGu 大</a> 的文章：<a href="http://weblogs.asp.net/scottgu/archive/2005/10/06/426755.aspx">App_Offline.htm</a><br />
<br />
很鳥的是，.NET Documentation 裡完全沒提到這個。<br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/6689919.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/6689919.html</guid>
	<category>.Net</category>
	<pubDate>Thu, 07 Aug 2008 14:57:14 +0800</pubDate>
</item>
<item>
	<title>Mono 與音訊、視訊</title>
	<description><![CDATA[
			mplayer 的 -input 可以指定 file，man 裡面說明了你可以給一個 FIFO 的檔案。
藉著這個，於是就可以寫程式來控制 mplayer 來播放影片或是音樂。
你可以參考致遠管理學院資工系專題研究計畫研究成果報告計畫： Linux C# 設計 ...

你還可以使用 GStreamer#，Mono team 的人已經幫你將 gstreamer 函式庫包裝為 GStreamer#，因此使用 GStreamer# 也可以進行播放影片和音樂，最好的例子是 Banshee。
不過這只適用於 Linux。

		]]>
	</description>
	<content:encoded><![CDATA[
			<a href="http://www.mplayerhq.hu/">mplayer</a> 的 -input 可以指定 file，man 裡面說明了你可以給一個 FIFO 的檔案。<br />
藉著這個，於是就可以寫程式來控制 <a href="http://www.mplayerhq.hu/">mplayer</a> 來播放影片或是音樂。<br />
你可以參考<a href="http://mail2.dwu.edu.tw/~ezliang/Project_Unix/Projetc_report_96A.pdf">致遠管理學院資工系專題研究計畫研究成果報告計畫： Linux C# 設計 ...</a><br />
<br />
你還可以使用 <a href="http://www.mono-project.com/Gstreamer">GStreamer#</a>，<a href="http://www.mono-project.com/">Mono</a> team 的人已經幫你將 <a href="http://www.gstreamer.org/">gstreamer</a> 函式庫包裝為 <a href="http://www.mono-project.com/Gstreamer">GStreamer#</a>，因此使用 <a href="http://www.mono-project.com/Gstreamer">GStreamer#</a> 也可以進行播放影片和音樂，最好的例子是 <a href="http://www.banshee-project.com/">Banshee</a>。<br />
不過這只適用於 Linux。<br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/6658157.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/6658157.html</guid>
	<category>.Net</category>
	<pubDate>Tue, 05 Aug 2008 17:49:15 +0800</pubDate>
</item>
<item>
	<title>.NET framework essential Chapter 6-Web Services</title>
	<description><![CDATA[
			最前面是一堆有點誇張的介紹，不過在當時大家真的都以為 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>
	<content:encoded><![CDATA[
			最前面是一堆有點誇張的介紹，不過在當時大家真的都以為 Web Services 很棒...<br />
這一章介紹 Web Services 的觀念與實作，由於微軟是規格制定者，所以 .NET 對 Web Services 的支援不能少，下了很多功夫。<br />
主角是 WebService 類別與 WebMethodAttribute，方法是繼承 WebService 類別，然後在要被呼叫的方法上，標上 WebMethod attribute。<br />
<br />
以前以為 Web Services 的底層是 SOAP，所以只能用 SOAP，沒想到也可以用 GET/POST 的方式來呼叫，所以 javascript 也能輕易地呼叫 Web Services，然後解析回傳的 XML 即可。<br />
Security 方面，以前也以為沒有 session，現在也知道可以用了。另外還介紹了兩種層級的保護，系統層級是利用 IIS 管理介面設定權限與 SSL 來達成，Application Level，則是利用 .NET 的 web.config 來達成。<br />
SSL 對於 Web Service 來說，是個稍嫌沈重的負擔，所以他也建議使用 authentication token 的方式，也就是提供一個架構在 SSL 上，可以取得 authentication token 的方法，取得 token 之後，後續的呼叫都要帶入這個 token，以作為識別。<br />
這樣的方式，在目前有提供 Open API 的網站上很常見。<br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/6638049.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/6638049.html</guid>
	<category>.Net</category>
	<pubDate>Fri, 01 Aug 2008 13:33:47 +0800</pubDate>
</item>
<item>
	<title>MonoDevelop on Windows</title>
	<description><![CDATA[
			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 && make && 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 是反斜線 '\'，但 Cygwin 只能給 '/'，所以安裝 Mono.Addin 時，並沒有依照 Makefile 的指定，將 .dll 註冊到 gac 所以在編譯(make)、安裝(make install)後，你必須要手動將 .dll 註冊到 gac 裡：cd bin;find . -name '*.dll' -exec gacutil -i {} \;

接著，MonoDevelop 就 build 成功了。不過，MonoDevelop 還是不能執行 :-( MonoDevelop.Core.Gui.Services 這邊會丟出例外。

		]]>
	</description>
	<content:encoded><![CDATA[
			<a href="http://www.cygwin.com/">Cygwin</a> 要裝些什麼可以參考這篇：<a href="http://www.codeproject.com/KB/cross-platform/mono_on_windows.aspx">CodeProject 上的文章：Building Mono on Windows: the final battle.</a><br/>
不過 <a href="http://www.mono-project.com/Main_Page">Mono</a> 可以直接用官方提供的，不需要自己 build。<br/>
<br/>
首先進 <a href="http://www.cygwin.com/">Cygwin</a> shell，設定 PATH 與 PKG_CONFIG_PATH，讓 <a href="http://www.cygwin.com/">Cygwin</a> 能找到 <a href="http://www.mono-project.com/Main_Page">Mono</a>：
<pre>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</pre>
<br/>
再把 <a href="http://www.mono-project.com/Main_Page">Mono</a> 目錄下的 pkg-config 更名，因為這個版本的 pkg-config 太舊。<br/>
<br/>
接著要 build Mono-Addin-0.3.1，這簡單，很快就 build 過了。(./configure && make && make install )<br/>
<br/>
再來就麻煩了，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 是比較順利了，順利的原因是，<a href="http://www.monodevelop.com/Main_Page">MonoDevelop</a> team 本來就有打算要出 Windows 版本，只是能不能用還在未知之數。<br/>
<br/>
在 build 的過程中，發現 gmcs 無法載入 Mono.Addin.Setup assembly 的問題，這是由於 gacutil 跟 <a href="http://www.cygwin.com/">Cygwin</a> 相處的不太好，gacutil 收的 path separator 是反斜線 '\'，但 <a href="http://www.cygwin.com/">Cygwin</a> 只能給 '/'，所以安裝 Mono.Addin 時，並沒有依照 Makefile 的指定，將 .dll 註冊到 gac 所以在編譯(make)、安裝(make install)後，你必須要手動將 .dll 註冊到 gac 裡：<pre>cd bin;find . -name '*.dll' -exec gacutil -i {} \;</pre>
<br/>
接著，<a href="http://www.monodevelop.com/Main_Page">MonoDevelop</a> 就 build 成功了。不過，<a href="http://www.monodevelop.com/Main_Page">MonoDevelop</a> 還是不能執行 :-( MonoDevelop.Core.Gui.Services 這邊會丟出例外。<br/>

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/6634735.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/6634735.html</guid>
	<category>.Net</category>
	<pubDate>Thu, 31 Jul 2008 20:06:16 +0800</pubDate>
</item>
<item>
	<title>.NET framework essential Chapter 4</title>
	<description><![CDATA[
			Chapter 3 主要是講各種語言的介紹與互相操作，大致都已經知道，沒什麼要紀錄的。
接著記 Chapter 4 的一些東西。

只要在 .config 裡面使用 bindingRedirect，就可以重新導向相依的assembly到新版本的assembly。.config 裡的 attribute：runtime / assemblyBinding / dependentAssemblyRemoting 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>
	<content:encoded><![CDATA[
			Chapter 3 主要是講各種語言的介紹與互相操作，大致都已經知道，沒什麼要紀錄的。<br />
接著記 Chapter 4 的一些東西。<br />
<br />
<ul><li>只要在 .config 裡面使用 bindingRedirect，就可以重新導向相依的assembly到新版本的assembly。.config 裡的 attribute：runtime / assemblyBinding / dependentAssembly</li><li>Remoting object 的程式真的出乎意料地簡單，以前從沒研究過，有機會來試試效能，看看傳一堆物件或是 Dataset 的效能如何。</li><li>有一個 Attribute 的簡單範例...</li><li>支援 Transaction 的要件：<ol><li>繼承 ServicedComponent</li><li>使用正確的 Transaction attribute</li></ol>接著就可用 System.EnterpriseServices.ContextUtil。此外最好也指定 ApplicationName、ApplicationActivation 等組件attribute。.NET 會在編譯時自動把組件加入 COM+ Service 裡，無須自己動手註冊。這邊還有 Object pooling、Role base、Message Queuing 的例子，很淺顯易懂。這部份在 Mono 裡都沒有被實作出來，主要是因為 COM+ 在 Linux 下沒有替代品的關係。</li></ul><br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/6298417.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/6298417.html</guid>
	<category>.Net</category>
	<pubDate>Thu, 03 Jul 2008 16:55:47 +0800</pubDate>
</item>
<item>
	<title>.NET essential 第二章 CLR 筆記</title>
	<description><![CDATA[
			主要是紀錄以前不知道或是看過沒深入了解的一些東西：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>
	<content:encoded><![CDATA[
			主要是紀錄以前不知道或是看過沒深入了解的一些東西：<ol><li>Managed C++ 編譯出來的執行檔無法用<a href="http://www.mono-project.com">mono</a>執行，可能是因為 Native code 跟 IL code 放到一起的關係。</li><li>從 stack-based 的 value type 轉成 heap-based 的 reference type 的過程稱作 boxing，反之稱作 unboxing。<pre name="code" class="csharp">int i=1;
object obj = i; // boxing
int j = (int)obj; // unboxing
</pre></li><li>為了要讓各種語言能在 CLR 上執行，有 Common Language Specification 的 ECMA 標準 - <a href="http://www.ecma-international.org/publications/standards/Ecma-335.htm">Standard ECMA-335</a>。</li><li>NGen 可以預先將 IL code 轉為 Native executable code，省掉 JIT compiler 的工作(pre-JITting)，因此可以加速。<a href="http://www.mono-project.com">mono</a>裡似乎是用 <pre>mono -O=all --aot your-assembly</pre> 來替代的樣子。</li></ol>

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/6217521.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/6217521.html</guid>
	<category>.Net</category>
	<pubDate>Mon, 23 Jun 2008 11:24:43 +0800</pubDate>
</item>
<item>
	<title>ILMerge</title>
	<description><![CDATA[
			這工具可以讓你把 .Net 不同語言編譯出來的 Assembly (組件)合併在一起。

官方網址：ILMerge

安裝以後，用法很簡單：
"c:\Program Files\Microsoft\ILMerge\ILMerge.exe" /t:library /out:[輸出檔名] /lib:[Assembly搜索路徑] [要合併的 Assembly 1] [要合併的 Assembly 2] ...

只想給客戶一個可執行檔，不想給一堆其他組件的時候，這樣作也行：
"c:\Program Files\Microsoft\ILMerge\ILMerge.exe" /t:[exe或winexe] /out:[輸出檔名] /lib:[Assembly搜索路徑] [執行檔] [要合併的 Assembly 1] [要合併的 Assembly 2] ...

對，合併以後，檔案絕對變大，然後千萬不要忘記了，要測試。另外，ILMerge 文件(ILMerge.doc)裡面有些限制以及問題，甚至是用法都有詳細描述，要記得閱讀...

		]]>
	</description>
	<content:encoded><![CDATA[
			這工具可以讓你把 .Net 不同語言編譯出來的 Assembly (組件)合併在一起。<br />
<br />
官方網址：<a href="http://research.microsoft.com/~mbarnett/ILMerge.aspx">ILMerge</a><br />
<br />
安裝以後，用法很簡單：<br />
<pre>"c:\Program Files\Microsoft\ILMerge\ILMerge.exe" /t:library /out:[輸出檔名] /lib:[Assembly搜索路徑] [要合併的 Assembly 1] [要合併的 Assembly 2] ...</pre><br />
<br />
只想給客戶一個可執行檔，不想給一堆其他組件的時候，這樣作也行：<br />
<pre>"c:\Program Files\Microsoft\ILMerge\ILMerge.exe" /t:[exe或winexe] /out:[輸出檔名] /lib:[Assembly搜索路徑] [執行檔] [要合併的 Assembly 1] [要合併的 Assembly 2] ...</pre><br />
<br />
對，合併以後，檔案絕對變大，然後千萬不要忘記了，要測試。另外，ILMerge 文件(ILMerge.doc)裡面有些限制以及問題，甚至是用法都有詳細描述，要記得閱讀...<br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/6027919.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/6027919.html</guid>
	<category>.Net</category>
	<pubDate>Thu, 15 May 2008 15:16:32 +0800</pubDate>
</item>
<item>
	<title>包在 Mono Windows 版裡的東西</title>
	<description><![CDATA[
			再隨手記下一些：
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 generatormonop、monop2，把類別的公開介面列出來的 console 程式monolinker，可以只把需要的類別抽取出來或是把一些程式安插進去的程式。

		]]>
	</description>
	<content:encoded><![CDATA[
			再隨手記下一些：<br />
<ul><li>VisualPng.exe，可以看 png 的軟體</li><li>webshot.bat，可以抓取網頁當作圖片的 console 程式，不過在 Windows 跑不起來，會丟出需要 gtkembedmoz 的錯誤訊息</li><li>ipy、ipy2，是的，有把 IronPython 包進來，不過互動模式怪怪的。</li><li>ikvm，這是之前就有的，詳情請參考<a href="http://www.ikvm.net/">ikvm</a>官方網頁說明，是可以讓 Java 程式在 mono 上執行的程式(甚至是互轉)</li><li>jay，類似 yacc 的 parser，是的，c# compiler 就是以此為基礎</li><li>xulrunner，好像是這一版才加入的，印象中之前並沒有，用途不明...</li><li>cilc，用途不明，help 是寫：Mono CIL-to-C binding generator</li><li>monop、monop2，把類別的公開介面列出來的 console 程式</li><li>monolinker，可以只把需要的類別抽取出來或是把一些程式安插進去的程式。</li></ul><br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/5831551.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/5831551.html</guid>
	<category>.Net</category>
	<pubDate>Tue, 08 Apr 2008 16:49:33 +0800</pubDate>
</item>
<item>
	<title>pythonw 與 monow</title>
	<description><![CDATA[
			Windows 版的 Python 在安裝以後，你會發現目錄下除了 python.exe 以外，還有一個 pythonw.exe，這是做什麼的呢？
簡單的說，python.exe 是一個 console 程式，執行 Python 程式的時候，在建立捷徑的時候，你會這樣寫：python your_app.py，但是執行時會出現一個黑色的 console 視窗。
pythonw.exe 作用則在於，不出現那個黑色的 console 視窗。

好，那 monow 的作用為何，你應該也能了解了吧～

特別指出這個的原因，是因為我這幾天在看 Mono 裝了什麼東西時發現的，其實我陸續還有看到一些東西，慢慢再介紹。

		]]>
	</description>
	<content:encoded><![CDATA[
			Windows 版的 <a href="http://python.org/">Python</a> 在安裝以後，你會發現目錄下除了 python.exe 以外，還有一個 pythonw.exe，這是做什麼的呢？<br />
簡單的說，python.exe 是一個 console 程式，執行 <a href="http://python.org/">Python</a> 程式的時候，在建立捷徑的時候，你會這樣寫：python your_app.py，但是執行時會出現一個黑色的 console 視窗。<br />
pythonw.exe 作用則在於，不出現那個黑色的 console 視窗。<br />
<br />
好，那 monow 的作用為何，你應該也能了解了吧～<br />
<br />
特別指出這個的原因，是因為我這幾天在看 <a href="http://www.mono-project.com">Mono</a> 裝了什麼東西時發現的，其實我陸續還有看到一些東西，慢慢再介紹。<br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/5824561.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/5824561.html</guid>
	<category>.Net</category>
	<pubDate>Mon, 07 Apr 2008 14:10:52 +0800</pubDate>
</item>
<item>
	<title>亂碼 1/2</title>
	<description><![CDATA[
			此亂碼非彼亂馬啊～
家裏 Server 的 Mono 升級到 1.9 以後，ASP.Net 網頁裡的中文突然都變成了亂碼，可是我什麼都沒改啊～
由於個人因素 (就是懶啦)，一直都沒去管，今天看開了，決定找出真兇...

首先試著直接跑 xsp2 之後，用 Browser 去看結果，正常，沒有亂碼。很好，那麼應該是 mod_mono 跟 Apache 的問題囉～
再看看有亂碼的網頁，看看送出來的網頁與 Response header 是否正確，送出來網頁的中文都變成了 ?，可是從資料庫撈出來的字卻又都沒問題，可以正常顯示，網頁的 Response header 也沒問題。很好，那真的是 mod_mono 與 Apache 的問題了。

仔細看了 mod_mono 的設定，唯一我覺得有問題的，就是 MonoSetEnv，可是我確實地已經設定了 MonoSetEnv "LANG=en_US.UTF-8"，應該不會有問題才對。
好，那麼就寫個簡單的網頁把所有環境變數列出來看看，果不其然，LANG = C，這表示LANG並沒有被設定，那麼會出現亂碼也是很正常的了。LANG 對 Linux 來說，是很重要的環境變數，沒有這個，很多應用程式將無法判斷目前所在的語系與編碼。
那麼是 mod_mono 問題囉？可是看過 source code 之後，發現沒有特別針對 MonoSetEnv 做什麼修正，再回頭看看列出來的環境變數，我發現我在設定檔裡面設定的 TEMP 環境變數有生效，那麼?!

再仔細看一次 mod_mono 的說明，原來如果你要設定多個環境變數時，要加上 ';'，所以在我改寫為 MonoSetEnv "LANG=en_US.UTF-8;TEMP=/var/tmp"，重新啟動之後，問題就解決了。

p.s. 那...為啥以前沒錯?! 我想可能是 Apache 的 apr 行為有改變吧～

		]]>
	</description>
	<content:encoded><![CDATA[
			此亂碼非彼<a href="http://zh.wikipedia.org/wiki/%E4%B9%B1%E9%A9%AC">亂馬</a>啊～<br />
家裏 Server 的 <a href="http://www.mono-project.com">Mono</a> 升級到 1.9 以後，ASP.Net 網頁裡的中文突然都變成了亂碼，可是我什麼都沒改啊～<br />
由於個人因素 (就是懶啦)，一直都沒去管，今天看開了，決定找出真兇...<br />
<br />
首先試著直接跑 xsp2 之後，用 Browser 去看結果，正常，沒有亂碼。很好，那麼應該是 mod_mono 跟 Apache 的問題囉～<br />
再看看有亂碼的網頁，看看送出來的網頁與 Response header 是否正確，送出來網頁的中文都變成了 ?，可是從資料庫撈出來的字卻又都沒問題，可以正常顯示，網頁的 Response header 也沒問題。很好，那真的是 mod_mono 與 Apache 的問題了。<br />
<br />
仔細看了 mod_mono 的設定，唯一我覺得有問題的，就是 MonoSetEnv，可是我確實地已經設定了 MonoSetEnv "LANG=en_US.UTF-8"，應該不會有問題才對。<br />
好，那麼就寫個簡單的網頁把所有環境變數列出來看看，果不其然，LANG = C，這表示LANG並沒有被設定，那麼會出現亂碼也是很正常的了。LANG 對 Linux 來說，是很重要的環境變數，沒有這個，很多應用程式將無法判斷目前所在的語系與編碼。<br />
那麼是 mod_mono 問題囉？可是看過 <a href="http://anonsvn.mono-project.com/viewcvs/trunk/mod_mono/src/">source code</a> 之後，發現沒有特別針對 MonoSetEnv 做什麼修正，再回頭看看列出來的環境變數，我發現我在設定檔裡面設定的 TEMP 環境變數有生效，那麼?!<br />
<br />
再仔細看一次 mod_mono 的說明，原來如果你要設定多個環境變數時，要加上 ';'，所以在我改寫為 MonoSetEnv "LANG=en_US.UTF-8;TEMP=/var/tmp"，重新啟動之後，問題就解決了。<br />
<br />
p.s. 那...為啥以前沒錯?! 我想可能是 <a href="http://httpd.apache.org">Apache</a> 的 apr 行為有改變吧～<br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/5797269.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/5797269.html</guid>
	<category>.Net</category>
	<pubDate>Wed, 02 Apr 2008 17:05:17 +0800</pubDate>
</item>
<item>
	<title>c# Iterator</title>
	<description><![CDATA[
			這裡沒有要解說什麼，下面這段程式是從 c# specification 來的，而程式本來是不能執行的，是的，範例有問題。問題點：原本的 IEnumerator&lt;T&gt; GetEnumerator() 應該加上 IEnumerable&lt;T&gt;.，成為 IEnumerator&lt;T&gt; IEnumerable&lt;T&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&lt;T&gt;: IEnumerable&lt;T&gt;, IEnumerable
{
	T value;
	Tree&lt;T&gt; left;
	Tree&lt;T&gt; right;
	public Tree(T value, Tree&lt;T&gt; left, Tree&lt;T&gt; right) {
		this.value = value;
		this.left = left;
		this.right = right;
	}
	
	IEnumerator&lt;T&gt; IEnumerable&lt;T&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 &lt;http://weblogs.asp.net/bleroy/archive/2004/08/31/223531.aspx&gt;
	IEnumerator IEnumerable.GetEnumerator() {
		return (IEnumerator)(((IEnumerable&lt;T>)this).GetEnumerator());
	}
}

public class Program
{
	static Tree&lt;T&gt; MakeTree&lt;T&gt;(T[] items, int left, int right) {
		if (left &gt; right) 
			return null;
		int i = (left + right) / 2;
		return new Tree&lt;T&gt;(items[i], 
			MakeTree(items, left, i - 1),
			MakeTree(items, i + 1, right));
	}
	static Tree&lt;T&gt; MakeTree&lt;T&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&lt;int&gt; ints = MakeTree(1, 2, 3, 4, 5, 6, 7, 8, 9);
		foreach (int i in ints) 
			Console.Write("{0} ", i);
		Console.WriteLine();
		Tree&lt;string&gt; strings = MakeTree(
			"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun");
		foreach (string s in strings) 
			Console.Write("{0} ", s);
		Console.WriteLine();
		Console.ReadLine();
	}
}


額外的收穫是，發現 mono gmcs 編譯出來的代碼比 Microsoft csc 編譯出來的代碼要多出約四百多個 bytes。

		]]>
	</description>
	<content:encoded><![CDATA[
			這裡沒有要解說什麼，下面這段程式是從 c# specification 來的，而程式本來是不能執行的，是的，範例有問題。問題點：<ol><li>原本的 IEnumerator&lt;T&gt; GetEnumerator() 應該加上 IEnumerable&lt;T&gt;.，成為 IEnumerator&lt;T&gt; IEnumerable&lt;T&gt;.GetEnumerator() <li><li>少繼承了 IEnumerable 介面並實做 IEnumerable.GetEnumerator()</li></ol><br/>
我查了很久，才找到問題點，另外還參考 <a href="http://weblogs.asp.net/bleroy/">Bertrand Le Roy</a> 的文章，精簡了 IEnumerable.GetEnumerator() 的代碼。<br/>
<br/>
Iterator 就類似 Python/Boo Generator 的概念，目前我認知到最大的好處是，不一定要讓迴圈全部跑完，就可以先傳回一個值去處理。<br/>
<br/>
<pre name="code" class="c#">using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;

public class Tree&lt;T&gt;: IEnumerable&lt;T&gt;, IEnumerable
{
	T value;
	Tree&lt;T&gt; left;
	Tree&lt;T&gt; right;
	public Tree(T value, Tree&lt;T&gt; left, Tree&lt;T&gt; right) {
		this.value = value;
		this.left = left;
		this.right = right;
	}
	
	IEnumerator&lt;T&gt; IEnumerable&lt;T&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 &lt;http://weblogs.asp.net/bleroy/archive/2004/08/31/223531.aspx&gt;
	IEnumerator IEnumerable.GetEnumerator() {
		return (IEnumerator)(((IEnumerable&lt;T>)this).GetEnumerator());
	}
}

public class Program
{
	static Tree&lt;T&gt; MakeTree&lt;T&gt;(T[] items, int left, int right) {
		if (left &gt; right) 
			return null;
		int i = (left + right) / 2;
		return new Tree&lt;T&gt;(items[i], 
			MakeTree(items, left, i - 1),
			MakeTree(items, i + 1, right));
	}
	static Tree&lt;T&gt; MakeTree&lt;T&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&lt;int&gt; ints = MakeTree(1, 2, 3, 4, 5, 6, 7, 8, 9);
		foreach (int i in ints) 
			Console.Write("{0} ", i);
		Console.WriteLine();
		Tree&lt;string&gt; strings = MakeTree(
			"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun");
		foreach (string s in strings) 
			Console.Write("{0} ", s);
		Console.WriteLine();
		Console.ReadLine();
	}
}
</pre>

額外的收穫是，發現 mono gmcs 編譯出來的代碼比 Microsoft csc 編譯出來的代碼要多出約四百多個 bytes。

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/5574113.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/5574113.html</guid>
	<category>.Net</category>
	<pubDate>Thu, 21 Feb 2008 18:12:01 +0800</pubDate>
</item>
<item>
	<title>ASP.Net in Debian/Ubuntu</title>
	<description><![CDATA[
			在 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 設定裡面加上：    &lt;Proxy *&gt;
        Order deny,allow
        Allow from all
    &lt;/Proxy&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/

    &lt;Location /your_app_name&gt;
        ProxyPassReverse /
        SetOutputFilter proxy-html
        ProxyHTMLURLMap / /your_app_name/
        Order allow,deny
        Allow from all
    &lt;/Location&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 - ConfluenceRunning a Reverse Proxy with Apache:mod_proxy_html

		]]>
	</description>
	<content:encoded><![CDATA[
			在 <a href="http://www.ubuntulinux.com">Ubuntu</a> 下架設 mono xsp 其實還蠻愉快的。<br/>
<a href="http://www.debian.org">Debian</a>/<a href="http://www.ubuntulinux.com">Ubuntu</a>的mono-xsp2套件提供了 mono-xsp2-admin 指令，用這個很快就能新增/刪除你的應用程式。<br/>
用法很簡單：<pre>sudo mono-xsp2-admin add --path=your_app_path --application=/your_app_name</pre>
接著重新啟動 mono-xsp2 服務即可：<pre>sudo /etc/init.d/mono-xsp2 restart</pre>
這個方法不需要安裝 mod_mono，因為這個時候 xsp2 是以一個獨立的 Daemon 存在。如果你希望 xsp2 應用程式是作為 <a href="http://httpd.apache.org">Apache</a> Web server 下的一個子目錄的話，你需要安裝 mod_proxy, mod_proxy_http, mod_proxy_html：<pre>sudo apt-get install libapache2-proxy-html
sudo a2enmod proxy proxy_html</pre>

然後在你的 VirtualHost 設定裡面加上：<pre>    &lt;Proxy *&gt;
        Order deny,allow
        Allow from all
    &lt;/Proxy&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/

    &lt;Location /your_app_name&gt;
        ProxyPassReverse /
        SetOutputFilter proxy-html
        ProxyHTMLURLMap / /your_app_name/
        Order allow,deny
        Allow from all
    &lt;/Location&gt;
</pre>
<br/>
接著重新啟動 Apache，這時候你在瀏覽器的網址列輸入 http://localhost/your_app_name/ 應該就可以存取到你的 asp.net 應用程式了。<br/>
<br/>
備註：如果你不想使用 mono-xsp2，而只想把 Apache 當作前端，IIS當後端的話，同樣也可以用 mod_proxy, mod_proxy_html, mod_proxy_http 來解。<br/>
<br/>
參考資料：<ul><li><a href="http://confluence.atlassian.com/display/DOC/Using+Apache+with+mod_proxy">Using Apache with mod_proxy - Confluence 2.7 - Confluence</a></li><li><a href="http://www.apachetutor.org/admin/reverseproxies">Running a Reverse Proxy with Apache:</a></li><li><a href="http://apache.webthing.com/mod_proxy_html/config.html">mod_proxy_html</a></li></ul>

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/5500251.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/5500251.html</guid>
	<category>.Net</category>
	<pubDate>Mon, 04 Feb 2008 17:04:52 +0800</pubDate>
</item>
<item>
	<title>String.IsNullOrEmpty</title>
	<description><![CDATA[
			長見識，原來 .Net framework 2 之後為 String 多提供了一個方便的 Method：IsNullOrEmpty

所以以後可以不用寫成這樣了：
string s;
if( s!=null && s!=String.Empty )
{
  // do something
}


補充：不過有文章(DANGER ! String.IsNullOrEmpty can lead to runtime Null exceptions !! - @ Head)指出這方法其實有可能會丟出 Null exception.

		]]>
	</description>
	<content:encoded><![CDATA[
			<a href="http://blogs.msdn.com/vijaysk/archive/2008/01/24/anatomy-of-forms-authentication-return-url.aspx" title="Anatomy of ASP.NET Forms Authentication Return URL">長見識</a>，原來 .Net framework 2 之後為 String 多提供了一個方便的 Method：<a href="http://msdn2.microsoft.com/en-us/library/system.string.isnullorempty.aspx">IsNullOrEmpty</a><br/>
<br/>
所以以後可以不用寫成這樣了：<pre name="code" class="c#">
string s;
if( s!=null && s!=String.Empty )
{
  // do something
}
</pre>
<br/>
補充：不過有文章(<a href="http://msmvps.com/blogs/bill/archive/2006/04/04/89234.aspx">DANGER ! String.IsNullOrEmpty can lead to runtime Null exceptions !! - @ Head</a>)指出這方法其實有可能會丟出 Null exception.

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/5133623.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/5133623.html</guid>
	<category>.Net</category>
	<pubDate>Fri, 25 Jan 2008 09:45:20 +0800</pubDate>
</item>
<item>
	<title>為 Mono c# 編譯器的輸出添加一點色彩</title>
	<description><![CDATA[
			Miguel 大日前為 Mono c# 編譯器加了一點小小的加強(Colorful Error Output)，只要設定MCS_COLOR環境變數，就可以讓編譯器的輸出有比較顯目的色彩：
export MCS_COLORS=errors=brightwhite,red

如果你要關閉這功能的話，只要用
export MCS_COLORS=disable
就可以關閉。

不過照文章的日期看來，這功能應該在 1.2.7 以後才會有～

		]]>
	</description>
	<content:encoded><![CDATA[
			<a href="http://tirania.org/blog/">Miguel 大</a>日前為 Mono c# 編譯器加了一點小小的加強(<a href="http://tirania.org/blog/archive/2007/Dec-21-1.html">Colorful Error Output</a>)，只要設定MCS_COLOR環境變數，就可以讓編譯器的輸出有比較顯目的色彩：<br />
<pre>export MCS_COLORS=errors=brightwhite,red</pre><br />
<br />
如果你要關閉這功能的話，只要用<br />
<pre>export MCS_COLORS=disable</pre><br />
就可以關閉。<br />
<br />
不過照<a href="http://tirania.org/blog/archive/2007/Dec-21-1.html" title="Colorful Error Output">文章</a>的日期看來，這功能應該在 1.2.7 以後才會有～<br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/4963207.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/4963207.html</guid>
	<category>.Net</category>
	<pubDate>Fri, 11 Jan 2008 18:10:11 +0800</pubDate>
</item>
<item>
	<title>在 Monorail 裡啟動 Logging 的方法</title>
	<description><![CDATA[
			參考這篇：Enabling logging就行了。

整理如下：
在 public 下新增一個檔案 log4net.config：
&lt;?xml version="1.0" encoding="utf-8" ?&gt;
&lt;configuration&gt;
    &lt;log4net&gt;
        &lt;!-- Define some output appenders --&gt;
        &lt;appender name="rollingFile" type="log4net.Appender.RollingFileAppender,log4net" &gt;
            &lt;param name="File" value="log.txt" /&gt;
            &lt;param name="AppendToFile" value="true" /&gt;
            &lt;param name="RollingStyle" value="Date" /&gt;
            &lt;param name="DatePattern" value="yyyy.MM.dd" /&gt;
            &lt;param name="StaticLogFileName" value="true" /&gt;
            &lt;layout type="log4net.Layout.PatternLayout,log4net"&gt;
                &lt;param name="ConversionPattern" value="%d [%t] %-5p %c [%x] (%X{auth}) - %m%n" /&gt;
            &lt;/layout&gt;
        &lt;/appender&gt;
        &lt;root&gt;
            &lt;!-- priority value can be set to ALL|INFO|WARN|ERROR --&gt;
            &lt;priority value="INFO" /&gt;
            &lt;appender-ref ref="rollingFile" /&gt;
        &lt;/root&gt;
    &lt;/log4net&gt;
&lt;/configuration&gt;

在 public/web.config 裡面，註冊 service：
&lt;monorail&gt;
    &lt;services&gt;
        &lt;service 
            id="Custom" 
            interface="Castle.Core.Logging.ILoggerFactory, Castle.Core"
            type="Castle.Services.Logging.Log4netIntegration.Log4netFactory, Castle.Services.Logging.Log4netIntegration" /&gt;
    &lt;/services&gt;
    &lt;!--略...--&gt;


		]]>
	</description>
	<content:encoded><![CDATA[
			參考這篇：<a href="http://www.castleproject.org/monorail/documentation/v1rc2/advanced/enablinglogging.html">Enabling logging</a>就行了。<br/>
<br/>
整理如下：
<ol><li>在 public 下新增一個檔案 log4net.config：<pre name="code" class="xml">
&lt;?xml version="1.0" encoding="utf-8" ?&gt;
&lt;configuration&gt;
    &lt;log4net&gt;
        &lt;!-- Define some output appenders --&gt;
        &lt;appender name="rollingFile" type="log4net.Appender.RollingFileAppender,log4net" &gt;
            &lt;param name="File" value="log.txt" /&gt;
            &lt;param name="AppendToFile" value="true" /&gt;
            &lt;param name="RollingStyle" value="Date" /&gt;
            &lt;param name="DatePattern" value="yyyy.MM.dd" /&gt;
            &lt;param name="StaticLogFileName" value="true" /&gt;
            &lt;layout type="log4net.Layout.PatternLayout,log4net"&gt;
                &lt;param name="ConversionPattern" value="%d [%t] %-5p %c [%x] (%X{auth}) - %m%n" /&gt;
            &lt;/layout&gt;
        &lt;/appender&gt;
        &lt;root&gt;
            &lt;!-- priority value can be set to ALL|INFO|WARN|ERROR --&gt;
            &lt;priority value="INFO" /&gt;
            &lt;appender-ref ref="rollingFile" /&gt;
        &lt;/root&gt;
    &lt;/log4net&gt;
&lt;/configuration&gt;
</pre></li>
<li>在 public/web.config 裡面，註冊 service：<pre name="code" class="xml">
&lt;monorail&gt;
    &lt;services&gt;
        &lt;service 
            id="Custom" 
            interface="Castle.Core.Logging.ILoggerFactory, Castle.Core"
            type="Castle.Services.Logging.Log4netIntegration.Log4netFactory, Castle.Services.Logging.Log4netIntegration" /&gt;
    &lt;/services&gt;
    &lt;!--略...--&gt;
</pre></li></ol>

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/4784799.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/4784799.html</guid>
	<category>.Net</category>
	<pubDate>Mon, 07 Jan 2008 17:10:01 +0800</pubDate>
</item>
<item>
	<title>Monorail ActiveRecord Scaffold</title>
	<description><![CDATA[
			今天看官方文件時，看到這個：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>
	<content:encoded><![CDATA[
			今天看官方文件時，看到這個：<a href="http://www.castleproject.org/monorail/documentation/v1rc2/integration/arscaffold.html">ActiveRecord Scaffold</a><br/>
只要有 model，monorail 可以自動幫你把 controller configure 成有 scaffold 功能 (CRUD都具備) 的 controller：
<pre name="code" class="c#">
[Scaffolding( typeof(Blog) )]
public class BlogsController : Controller
{
}
</pre>
<br/>
這真是令人驚訝...不過 rc2 預設的 Layout 有問題，所以你最好加上 [Layout] attribute，自訂 Layout 比較好...<br/>
缺點是，要作 localization 的話，依照現在 rc2 的代碼，根本不可能...<br/>
<br/>
結論是，有空可以來看看這邊的代碼(ARFormHelper.cs/PresentationHelper.cs)，因為 Generator 裡面的 ScaffoldHelper 有些情況沒考慮的很仔細。<br/>

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/4770977.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/4770977.html</guid>
	<category>.Net</category>
	<pubDate>Fri, 04 Jan 2008 16:40:44 +0800</pubDate>
</item>
<item>
	<title>How to monorail by Generator tool(4)</title>
	<description><![CDATA[
			在研究過之後，我決定在 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, "Name" )

當然你還是可以用原先的方法：

$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, "First" );
        string prevText = GetText( resource, "Previous" );
        string nextText = GetText( resource, "Next" );
        string lastText = GetText( resource, "Last" );
			
        if (page.HasFirst)
            output.Write(helper.CreatePageLink(1, firstText ));
        else
            output.Write( firstText );
	
        output.Write(" | ");
			
        if (page.HasPrevious)
            output.Write(helper.CreatePageLink(page.PreviousIndex, prevText ));
        else
            output.Write(prevText);
        
        output.Write(" | ");
        
        if (page.HasNext) 
            output.Write(helper.CreatePageLink(page.NextIndex, nextText ));
        else
            output.Write( nextText );
        
        output.Write(" | ");
        
        if (page.HasLast) 
            output.Write(helper.CreatePageLink(page.LastIndex, lastText ));
        else
            output.Write( lastText );
			
        return output.ToString();
    }
    #endregion


最後在資源檔裡面加上必要的字串並且修改 .vm (template)以後，就可以得到本土化後的結果。

		]]>
	</description>
	<content:encoded><![CDATA[
			在研究過之後，我決定在 ScaffoldHelper.cs 裡面添加 GetText 這個函數，用來取得字串。
<pre name="code" class="c#">
    #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
</pre>
這樣在 .vm (template)檔案裡面，就可以這麼使用，以取得本地化後的字串：
<pre name="code" class="html">
$ScaffoldHelper.GetText($textres, "Name" )
</pre>
當然你還是可以用原先的方法：
<pre name="code" class="html">
$textres.Name
</pre>

所以 PageBrowser() 也可以跟著修正為：
<pre name="code" class="c#">
    #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, "First" );
        string prevText = GetText( resource, "Previous" );
        string nextText = GetText( resource, "Next" );
        string lastText = GetText( resource, "Last" );
			
        if (page.HasFirst)
            output.Write(helper.CreatePageLink(1, firstText ));
        else
            output.Write( firstText );
	
        output.Write(" | ");
			
        if (page.HasPrevious)
            output.Write(helper.CreatePageLink(page.PreviousIndex, prevText ));
        else
            output.Write(prevText);
        
        output.Write(" | ");
        
        if (page.HasNext) 
            output.Write(helper.CreatePageLink(page.NextIndex, nextText ));
        else
            output.Write( nextText );
        
        output.Write(" | ");
        
        if (page.HasLast) 
            output.Write(helper.CreatePageLink(page.LastIndex, lastText ));
        else
            output.Write( lastText );
			
        return output.ToString();
    }
    #endregion
</pre>

最後在資源檔裡面加上必要的字串並且修改 .vm (template)以後，就可以得到本土化後的結果。

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/4727151.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/4727151.html</guid>
	<category>.Net</category>
	<pubDate>Wed, 26 Dec 2007 16:55:30 +0800</pubDate>
</item>
<item>
	<title>How to monorail by Generator tool(3)</title>
	<description><![CDATA[
			這一次要講的是 Localization，不幸的是 Generator 沒有考慮到 Localization 問題，所以由 Generator 產生出來的代碼，並不包含這部份，但這卻是一個很好的機會讓我去了解 Generator 與 monorail 底下的機制。

Castle官方網站上已經有介紹該怎麼 Localization：Resources and Localization，但不幸的是，他使用 Visual Studio.Net 作為範例，Visual Studio.Net 已經掩蓋了所有細節。
在研究官方文件與相關文件之後，以下是我的步驟。

首先，你要先在 app/controllers 加上：

	[Resource("textres", "ToDo.categories")]

這表示在 view(template) 那兒使用 $textres 就可以存取資源檔的內容。

所以在 app/views/categories/list.vm 裡，就可以把必要的字串改用$textres.字串名稱替代掉，這裡我就不列出整個 list.vm 了，只列出幾行：

	&lt;!--略--&gt;
	$HtmlHelper.LinkTo( $textres.AddNewCategory, "categories", "new")
	&lt;!--略--&gt;
	$HtmlHelper.LinkTo( $textres.View, "categories", "view", $category.Id)
	&lt;!--略--&gt;
	$HtmlHelper.LinkTo( $textres.Edit, "categories", "edit", $category.Id)
	&lt;!--略--&gt;
	$AjaxHelper.LinkToRemote( $textres.Delete, "delete.aspx", $DictHelper.CreateDict("with='id=$category.Id'", "condition=confirm('Delete?')", "onsuccess=new Effect.Fade('category$category.Id')"))
	&lt;!--略--&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，以便把資源檔編譯進去，這裡我也只列出關鍵的幾行：

	&lt;!--略--&gt;
	&lt;target name="build" description="Compile all source files"&gt;
		&lt;mkdir dir="${dir.bin}" /&gt;
		&lt;copy flatten="true" todir="${dir.bin}"&gt;
			&lt;fileset&gt;
				&lt;include name="${dir.lib.castle}/**" /&gt;
				&lt;include name="${dir.lib.npgsql}/**" /&gt;
				&lt;include name="${dir.lib.mysql}/**" /&gt;
				&lt;include name="${dir.lib.migrator}/**" /&gt;
				&lt;include name="${dir.lib.nunit}/nunit.framework.dll" /&gt;
			&lt;/fileset&gt;
		&lt;/copy&gt;
		&lt;resgen todir="${dir.src.app}/resources/"&gt;
			&lt;resources&gt;
				&lt;include name="${dir.src.app}/resources/*.txt" /&gt;
			&lt;/resources&gt;
		&lt;/resgen&gt;
		&lt;csc target="library" output="${dir.bin}/${project::get-name()}.dll"&gt;
			&lt;sources&gt;
				&lt;include name="${dir.config}/Boot.cs" /&gt;
				&lt;include name="${dir.src.app}/**/*.cs" /&gt;
				&lt;include name="${dir.src.test}/**/*.cs" /&gt;
				&lt;include name="${dir.migrations}/**/*.cs" /&gt;
			&lt;/sources&gt;
			&lt;resources basedir="." prefix="ToDo"&gt;
				&lt;include name="${dir.src.app}/resources/*.resources"/&gt;
			&lt;/resources&gt;
			&lt;references basedir="${dir.bin}"&gt;
				&lt;include name="System.Web.dll" /&gt;
	&lt;!--略--&gt;

最重要的就是 resgen 這個區塊與 csc 裡面的 resources 區塊，resgen 是把文字檔轉換為 .resources 資源檔，而 csc 裡面的 resources 則是表示要把產生出來的 .resources 編譯進去。

好了，該修改的都修改了，接下來就是重新建立，輸入 nant 就會自動重新編譯。
有點美中不足的是，下面顯示頁次的部份仍然是英文，這是因為這些字串被寫死在 ScaffoldHelper.cs 裡面，我想下次再來修改這部份。

後記：csc resources 所指定的 prefix 與 [Resource("textres", "ToDo.categories")] 的第二個參數息息相關，不妨修改來試試看。網站文件有提到 LocalizationFilter 的部份，但是用了卻不行，有待繼續研究。

		]]>
	</description>
	<content:encoded><![CDATA[
			這一次要講的是 Localization，不幸的是 Generator 沒有考慮到 Localization 問題，所以由 Generator 產生出來的代碼，並不包含這部份，但這卻是一個很好的機會讓我去了解 Generator 與 monorail 底下的機制。<br/>
<br/>
<a href="http://www.castleproject.org">Castle</a>官方網站上已經有介紹該怎麼 Localization：<a href="http://www.castleproject.org/monorail/documentation/v1rc2/usersguide/res_localization.html">Resources and Localization</a>，但不幸的是，他使用 Visual Studio.Net 作為範例，Visual Studio.Net 已經掩蓋了所有細節。
在研究官方文件與相關文件之後，以下是我的步驟。<br/>
<br/>
首先，你要先在 app/controllers 加上：
<pre name="code" class="c#">
	[Resource("textres", "ToDo.categories")]
</pre>
這表示在 view(template) 那兒使用 $textres 就可以存取資源檔的內容。<br/>
<br/>
所以在 app/views/categories/list.vm 裡，就可以把必要的字串改用<b>$textres.字串名稱</b>替代掉，這裡我就不列出整個 list.vm 了，只列出幾行：
<pre name="code" class="html">
	&lt;!--略--&gt;
	$HtmlHelper.LinkTo( $textres.AddNewCategory, "categories", "new")
	&lt;!--略--&gt;
	$HtmlHelper.LinkTo( $textres.View, "categories", "view", $category.Id)
	&lt;!--略--&gt;
	$HtmlHelper.LinkTo( $textres.Edit, "categories", "edit", $category.Id)
	&lt;!--略--&gt;
	$AjaxHelper.LinkToRemote( $textres.Delete, "delete.aspx", $DictHelper.CreateDict("with='id=$category.Id'", "condition=confirm('Delete?')", "onsuccess=new Effect.Fade('category$category.Id')"))
	&lt;!--略--&gt;
</pre>

然後我選擇在 app/ 下建立一個 resources 目錄，用來放置資源檔：
<pre>
;Filename: categories.txt
;Language: en-US
View=View
Edit=Edit
Delete=Delete
AddNewCategory=Add a new Category
</pre>
<pre>
;Filename: categories.zh-tw.txt
;Language: zh-tw
View=檢視
Edit=編輯
Delete=刪除
AddNewCategory=加新類別
</pre>
這裡要特別注意，把文字檔的編碼存為 unicode 或是 utf-8，否則會有亂碼出現。<br/>
<br/>
最後修改 default.build，以便把資源檔編譯進去，這裡我也只列出關鍵的幾行：
<pre name="code" class="html">
	&lt;!--略--&gt;
	&lt;target name="build" description="Compile all source files"&gt;
		&lt;mkdir dir="${dir.bin}" /&gt;
		&lt;copy flatten="true" todir="${dir.bin}"&gt;
			&lt;fileset&gt;
				&lt;include name="${dir.lib.castle}/**" /&gt;
				&lt;include name="${dir.lib.npgsql}/**" /&gt;
				&lt;include name="${dir.lib.mysql}/**" /&gt;
				&lt;include name="${dir.lib.migrator}/**" /&gt;
				&lt;include name="${dir.lib.nunit}/nunit.framework.dll" /&gt;
			&lt;/fileset&gt;
		&lt;/copy&gt;
		&lt;resgen todir="${dir.src.app}/resources/"&gt;
			&lt;resources&gt;
				&lt;include name="${dir.src.app}/resources/*.txt" /&gt;
			&lt;/resources&gt;
		&lt;/resgen&gt;
		&lt;csc target="library" output="${dir.bin}/${project::get-name()}.dll"&gt;
			&lt;sources&gt;
				&lt;include name="${dir.config}/Boot.cs" /&gt;
				&lt;include name="${dir.src.app}/**/*.cs" /&gt;
				&lt;include name="${dir.src.test}/**/*.cs" /&gt;
				&lt;include name="${dir.migrations}/**/*.cs" /&gt;
			&lt;/sources&gt;
			&lt;resources basedir="." prefix="ToDo"&gt;
				&lt;include name="${dir.src.app}/resources/*.resources"/&gt;
			&lt;/resources&gt;
			&lt;references basedir="${dir.bin}"&gt;
				&lt;include name="System.Web.dll" /&gt;
	&lt;!--略--&gt;
</pre>
最重要的就是 resgen 這個區塊與 csc 裡面的 resources 區塊，resgen 是把文字檔轉換為 .resources 資源檔，而 csc 裡面的 resources 則是表示要把產生出來的 .resources 編譯進去。<br/>
<br/>
好了，該修改的都修改了，接下來就是重新建立，輸入 nant 就會自動重新編譯。<br/>
有點美中不足的是，下面顯示頁次的部份仍然是英文，這是因為這些字串被寫死在 ScaffoldHelper.cs 裡面，我想下次再來修改這部份。<br/>
<br/>
後記：<ul><li>csc resources 所指定的 prefix 與 [Resource("textres", "ToDo.categories")] 的第二個參數息息相關，不妨修改來試試看。</li><li>網站文件有提到 LocalizationFilter 的部份，但是用了卻不行，有待繼續研究。</li></ul>

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/4722367.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/4722367.html</guid>
	<category>.Net</category>
	<pubDate>Tue, 25 Dec 2007 16:54:39 +0800</pubDate>
</item>
<item>
	<title>How to monorail by Generator tool(2)</title>
	<description><![CDATA[
			接下來，就參考這篇有名的 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，首先先產生"Category"，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: 找不到型別或命名空間名稱 'Category' (您是否遺漏 using 指示詞或組件參考?)
[csc] app\controllers\CategoriesController.cs(56,45): error CS0246: 找不到型別或命名空間名稱 'Category' (您是否遺漏 using 指示詞或組件參考?)
這個，得去修改 CategoriesController.cs，把 Category 都改為 Categories，這看來是 Generator 的問題。接著又再出現
error CS1501: 方法 'CreatePagination' 沒有任何多載使用 '2' 個引數，唉～這個錯誤訊息實在是太黯然又太銷魂...你必須再次修改 CategoriesController.cs，添加這兩行：
using System.Collections;
using System.Collections.Generic;
然後把 PropertyBag["categories"] = PaginationHelper.CreatePagination( Categories.FindAll(), 10);改為
PropertyBag["categories"] = PaginationHelper.CreatePagination( (IList)Categories.FindAll(), 10);，接下來應該就沒問題了。先試試看到目前為止的成果吧，輸入script\server，然後打開你的瀏覽器，在位址列輸入：http://localhost:8080/categories/list.aspx，就能看到結果了。

執行結果：


		]]>
	</description>
	<content:encoded><![CDATA[
			接下來，就參考這篇有名的 <a href="http://rails.homelinux.org/">Four Days on Rails</a> 來試試看吧～<br/>
首先呢，由於隔了這麼久才寫這篇，所以 Generator 改位置了，你得從這裡：<a href="http://svn.castleproject.org:8080/svn/castle/trunk/Experiments/Generator/">http://svn.castleproject.org:8080/svn/castle/trunk/Experiments/Generator/</a> Checkout，其他大致都跟上篇一樣。<br/>
<br/>
<ol><li>先利用 monorail ToDo，建立專案，接著依照上篇文章作必要的設定，同時我們使用 rc2，不使用最新的版本(也就是你不用更動 default.build)，設定的部份就不再贅述。</li><li>建立資料庫，這邊我是用<a href="http://www.mysql.com">MySQL</a>，建立的資料庫名稱是 ToDoDev，不過這只有跟修改連線字串有關係。</li><li>修改資料庫的連線字串，連線字串是放在 config/databases/ 下的 ActiveRecord 設定檔裡面，你可以看到這邊有兩個設定檔，他很貼心的把開發用與測試用的資料庫分開：development.xml、test.xml，事實上，你還可以增加一個 Production (或是其他名字)的 ActiveRecord 設定檔，表示這是正式上線用的資料庫。切換的時候，可以更動 config/boot.cs 以決定使用哪個 ActiveRecord 設定檔，預設是 development。</li><li>建立 Model，首先先產生"Category"，Category 的欄位如下：<blockquote>  id int autoincrement<br/>
  name varchar(255)<br/>
  created_on datetime<br/>
  updated_on datetime<br/>
</blockquote>，在專案的目錄下輸入：script\generate model Categories name created_on updated_on，這邊要注意的是，不需要特別寫 id，因為慣例至上，Generator會自動幫你增加 Id 這個欄位。Generator 會幫你作三件事情：產生 Category 這個類別、產生測試 Category 的 Unit test 類別以及建立資料表格的程式，你可以從指令的輸出結果很清楚的看到。<blockquote>    exists app\models<br/>
    create app\models\Categories.cs<br/>
    exists test\models<br/>
    create test\models\CategoriesTest.cs<br/>
    create db\migrations<br/>
    create db\migrations\001_AddCategoriesTable.cs<br/>
</blockquote></li><li>接下來，要去修改 Categories 類別的屬性型態，Generator 預設都是把型態設為字串，db\migrations 那邊則都是建立 varchar(50)。所以除了 app\models\Categories.cs 要修改型態之外，db\migrations\001_AddCategoriesTable.cs 下也要改！這邊把 Name 改為 255 個字元，created_on與updated_on 則改為 DateTime。</li><li>都修改完畢之後，就可以執行 nant migrate，這個步驟會幫你去實體資料庫作必要的事情。為甚麼要這樣子作？我想是因為一般資料庫的 script 是沒有作管理的，因此，才刻意把這些要去資料庫建立表格、修改欄位等的動作都放到 db\migrations 下，以便把這些程式也都納入版本控制。</li><li>執行 script\generate scaffold Category，這個步驟會一口氣幫你把 CRUD 的頁面都弄出來。</li><li>那麼，就編譯吧，直接執行 nant，只是卻出現了...<blockquote>[csc] app\controllers\CategoriesController.cs(36,72): error CS0246: 找不到型別或命名空間名稱 'Category' (您是否遺漏 using 指示詞或組件參考?)<br/>
[csc] app\controllers\CategoriesController.cs(56,45): error CS0246: 找不到型別或命名空間名稱 'Category' (您是否遺漏 using 指示詞或組件參考?)
</blockquote>這個，得去修改 CategoriesController.cs，把 Category 都改為 Categories，這看來是 Generator 的問題。接著又再出現
<blockquote>error CS1501: 方法 'CreatePagination' 沒有任何多載使用 '2' 個引數</blockquote>，唉～這個錯誤訊息實在是太黯然又太銷魂...你必須再次修改 CategoriesController.cs，添加這兩行：
<pre name="code" class="c#">using System.Collections;
using System.Collections.Generic;
</pre>然後把 <pre name="code" class="c#">PropertyBag["categories"] = PaginationHelper.CreatePagination( Categories.FindAll(), 10);</pre>改為
<pre name="code" class="c#">PropertyBag["categories"] = PaginationHelper.CreatePagination( (IList)Categories.FindAll(), 10);</pre>，接下來應該就沒問題了。</li><li>先試試看到目前為止的成果吧，輸入script\server，然後打開你的瀏覽器，在位址列輸入：http://localhost:8080/categories/list.aspx，就能看到結果了。</li></ol>
<br/>
執行結果：
<a href="http://www.flickr.com/photos/elleryq/2124463394/" title="categories_list_aspx"><img src="http://static.flickr.com/2153/2124463394_4d918e0fb1_m.jpg" title="categories_list_aspx" alt="categories_list_aspx" width="240" height="175" /></a>

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/4693005.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/4693005.html</guid>
	<category>.Net</category>
	<pubDate>Thu, 20 Dec 2007 14:53:35 +0800</pubDate>
</item>
<item>
	<title>Gtk# UI設計隨便聊</title>
	<description><![CDATA[
			前一陣子用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>
	<content:encoded><![CDATA[
			前一陣子用<a href="http://www.monodevelop.com">MonoDevelop</a>來寫 Gtk# 應用程式玩，發現真的是很簡單。<br />
幾乎可以跟 <a href="http://www.icsharpcode.net/OpenSource/SD/">SharpDevelop</a> 或 Visual Studio.Net 設計 Windows form 應用程式一樣了，同樣也是拖拉放，就可以完成。<br />
<br />
對於初入門的人來說，最痛苦的可能還是對於 Gtk# 的物件模型不熟悉，因為不熟悉，所以也就不知道該去處理哪些屬性與事件。<br />
好在<a href="http://www.go-mono.com">Mono</a>官方網站有提供入門文件：<ul><li><a href="http://www.mono-project.com/Category:GtkSharp">GtkSharp系列文件</a></li><li><a href="http://www.mono-project.com/GtkSharpBeginnersGuide">Beginners Guide</a></li></ul>用力唸一唸這些文件跟自己去嘗試，大致上應該是夠了。但這些文件大部分都是自己去寫 Layout code。<br />
<br />
如果你正在使用目前版本的 <a href="http://www.monodevelop.com">MonoDevelop</a> 在 Layout 的話，你會發現世界全然不同，因為<a href="http://www.monodevelop.com">MonoDevelop</a>引進了 <a href="http://www.mono-project.com/Stetic">Stetic</a>。<br />
現在使用 <a href="http://www.monodevelop.com">MonoDevelop</a> 拉出來的 Form，實際上都會被存放在專案目錄下的 gtk-gui 目錄下的某個 xml 檔案，在每次 build 之前，<a href="http://www.monodevelop.com">MonoDevelop</a> 會先把 xml 轉換為一個存放於 gtk-gui 目錄下的 partial 類別(.cs)，然後 build 的時候，再 build 到一起。而在專案目錄下所看到的代碼，只會有一行 Build()。<br />
這真的是方便很多，開發者只需要專注於如何處理程式邏輯就可以，而不需要去管 UI 代碼的生成。<br />
<br />
在 <a href="http://www.monodevelop.com">MonoDevelop</a> 加入 <a href="http://www.mono-project.com/Stetic">Stetic</a> 之前，大部分的 Gtk# 應用程式還是用手動加代碼或是用 Glade# 來設計介面（詳細的 Glade# 用法，可以參考 <a href="http://www.mono-project.com/GtkSharpBeginnersGuide#Your_First_Glade.23_Application">Your First Glade# Application</a> 的說明）。<br />
Glade# 其實也是把整個 UI 存成一個 xml 檔案，所以你得先使用 Glade 應用程式設計出 UI，得到 .glade 檔案，然後在程式裡面：<ol><li>載入 .glade 檔案</li><li>為控制項(Widget)加上 Attribute</li><li>撰寫事件處理並繫結</li></ol>。<br />
這當然是比手動寫代碼方便許多，但比起 <a href="http://www.mono-project.com/Stetic">Stetic</a>，還是要多作事，往往用 Glade 修改 UI 後，可能會忘記加必要的 Widget 宣告，或是對應的事件繫結。<br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/4674857.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/4674857.html</guid>
	<category>.Net</category>
	<pubDate>Tue, 18 Dec 2007 16:48:51 +0800</pubDate>
</item>
<item>
	<title>Gtk.TreeView(3)</title>
	<description><![CDATA[
			在 Linux 裡面，所謂的"事件"，多半是用 Signal 來表示，所以你看到 Signal 時，可以概略地當作"事件"來看。
而這些事件跟 Windows Form 的事件命名法差異相當大。
以下這些是比較常用到的：    protected virtual void OnTreeview1RowActivated (object o, Gtk.RowActivatedArgs args)
    {
        // double click
        Console.WriteLine( String.Format("[{0}]: {1}", o.GetType().ToString(), "row activated") );
    }
    
    protected virtual void OnTreeview1RowCollapsed (object o, Gtk.RowCollapsedArgs args)
    {
        // collapse
        Console.WriteLine( String.Format("[{0}]: {1}", o.GetType().ToString(), "row collapsed") );
    }
    
    protected virtual void OnTreeview1RowExpanded (object o, Gtk.RowExpandedArgs args)
    {
        // expand
        Console.WriteLine( String.Format("[{0}]: {1}", o.GetType().ToString(), "row expanded") );
    }
    
    protected virtual void OnTreeview1CursorChanged (object sender, System.EventArgs e)
    {
        // click
        Console.WriteLine( String.Format("[{0}]: {1}", sender.GetType().ToString(), "Cursor changed") );
    }


我是怎麼查到的呢？
坦白說，我是用笨方法，看到那些 Console.WriteLine 了沒？
我先試著在可能的事件裡面放置這些 Console.WriteLine，接著執行程式，試著去 Click、Expand，然後看 Console 輸出就知道了...

		]]>
	</description>
	<content:encoded><![CDATA[
			在 Linux 裡面，所謂的"事件"，多半是用 Signal 來表示，所以你看到 Signal 時，可以概略地當作"事件"來看。<br/>
而這些事件跟 Windows Form 的事件命名法差異相當大。<br/>
以下這些是比較常用到的：<pre name="code" class="c#">    protected virtual void OnTreeview1RowActivated (object o, Gtk.RowActivatedArgs args)
    {
        // double click
        Console.WriteLine( String.Format("[{0}]: {1}", o.GetType().ToString(), "row activated") );
    }
    
    protected virtual void OnTreeview1RowCollapsed (object o, Gtk.RowCollapsedArgs args)
    {
        // collapse
        Console.WriteLine( String.Format("[{0}]: {1}", o.GetType().ToString(), "row collapsed") );
    }
    
    protected virtual void OnTreeview1RowExpanded (object o, Gtk.RowExpandedArgs args)
    {
        // expand
        Console.WriteLine( String.Format("[{0}]: {1}", o.GetType().ToString(), "row expanded") );
    }
    
    protected virtual void OnTreeview1CursorChanged (object sender, System.EventArgs e)
    {
        // click
        Console.WriteLine( String.Format("[{0}]: {1}", sender.GetType().ToString(), "Cursor changed") );
    }
</pre>
<br/>
我是怎麼查到的呢？<br/>
坦白說，我是用笨方法，看到那些 Console.WriteLine 了沒？<br/>
我先試著在可能的事件裡面放置這些 Console.WriteLine，接著執行程式，試著去 Click、Expand，然後看 Console 輸出就知道了...

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/4662027.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/4662027.html</guid>
	<category>.Net</category>
	<pubDate>Mon, 17 Dec 2007 10:08:34 +0800</pubDate>
</item>
<item>
	<title>Gtk.TreeView (2)</title>
	<description><![CDATA[
			根據昨天的程式，稍作改良，就可以把整個目錄樹丟進去顯示了...
下面就是利用 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, "" );
			_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, "" );
		_buildTreeStore( store, di, root );
		return store;
	}

	public ExplorerSharp(): base(Gtk.WindowType.Toplevel)
	{
		Build();

		TreeStore store = buildTreeStore( "./" );

		// 設定資料來源  
		treeview1.Model = store;  

		// 不顯示表頭  
		treeview1.HeadersVisible = false;  

		// 設定要顯示的欄位  
		treeview1.AppendColumn("Name", new CellRendererText(), "Name", 1 );  
		treeview1.AppendColumn("Size", new CellRendererText(), "FileSize", 2 );  

		// 一次只能選定一列或一個節點  
		treeview1.Selection.Mode = Gtk.SelectionMode.Single;  
	}


		]]>
	</description>
	<content:encoded><![CDATA[
			根據昨天的程式，稍作改良，就可以把整個目錄樹丟進去顯示了...<br/>
下面就是利用 Recursive 來把資料塞到 TreeStore 裡面去。<br/>
<br/>
<pre name="code" class="c#">
	public void _buildTreeStore( TreeStore store, DirectoryInfo di, TreeIter parent )
	{
		foreach( DirectoryInfo iter in di.GetDirectories() )
		{
			TreeIter ti = store.AppendValues( parent, iter.FullName, iter.Name, "" );
			_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, "" );
		_buildTreeStore( store, di, root );
		return store;
	}

	public ExplorerSharp(): base(Gtk.WindowType.Toplevel)
	{
		Build();

		TreeStore store = buildTreeStore( "./" );

		// 設定資料來源  
		treeview1.Model = store;  

		// 不顯示表頭  
		treeview1.HeadersVisible = false;  

		// 設定要顯示的欄位  
		treeview1.AppendColumn("Name", new CellRendererText(), "Name", 1 );  
		treeview1.AppendColumn("Size", new CellRendererText(), "FileSize", 2 );  

		// 一次只能選定一列或一個節點  
		treeview1.Selection.Mode = Gtk.SelectionMode.Single;  
	}
</pre>

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/4629083.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/4629083.html</guid>
	<category>.Net</category>
	<pubDate>Wed, 12 Dec 2007 17:19:18 +0800</pubDate>
</item>
<item>
	<title>Gtk.TreeView (1)</title>
	<description><![CDATA[
			使用 TreeView 的基本，首先就是添加列與設定要顯示的欄。
呈現的方式，取決於你給 TreeView.Model 屬性的資料是什麼，如果是 TreeStore，就會顯示 Tree，如果是 ListStore，就會顯示 Grid。


    // 如果你把 TreeStore 改為 ListStore，就能得到類似 Grid 的效果。
    TreeStore store = new TreeStore();
    for( int i=0; i
		]]>
	</description>
	<content:encoded><![CDATA[
			使用 TreeView 的基本，首先就是添加列與設定要顯示的欄。<br/>
呈現的方式，取決於你給 TreeView.Model 屬性的資料是什麼，如果是 TreeStore，就會顯示 Tree，如果是 ListStore，就會顯示 Grid。<br/>
<br/>
<pre name="code" class="c#">
    // 如果你把 TreeStore 改為 ListStore，就能得到類似 Grid 的效果。
    TreeStore store = new TreeStore();
    for( int i=0; i<10; i++ )
    {
        TreeIter iter = store.AppendValues( "Demo " + i.ToString(), "" );
        // 添加子節點，你可以把這兩行註解掉試試看，這樣就沒有子節點了。
        for( int j=0; j<10; j++ )
            store.AppendValues( iter, "", "Child " + j.ToString() );
    }
    
    // 設定資料來源
    treeview1.Model = store;
    
    // 不顯示表頭
    treeview1.HeadersVisible = false;
    
    // 設定要顯示的欄位
    treeview1.AppendColumn("Name", new CellRendererText(), "i", 0 );
    treeview1.AppendColumn("Size", new CellRendererText(), "j", 1 );
    
    // 一次只能選定一列或一個節點
    treeview1.Selection.Mode = Gtk.SelectionMode.Single;
</pre>

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/4615599.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/4615599.html</guid>
	<category>.Net</category>
	<pubDate>Tue, 11 Dec 2007 15:58:08 +0800</pubDate>
</item>
<item>
	<title>Gtk.TreeView</title>
	<description><![CDATA[
			這幾天玩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>
	<content:encoded><![CDATA[
			這幾天玩<a href="http://www.monodevelop.com">MonoDevelop</a> Stetic (gtk# 的 UI designer) 的時候，發現 gtk# 裡的 TreeView Widget 是個很有趣的元件。<br />
有趣的原因，是因為他的設計哲學整個跟 Windows form 的設計哲學截然不同，Windows form 的 TreeView 就是很單純的 TreeView，沒別的。<br />
而 gtk# 的 TreeView Widget 則是以所謂的 MVC Pattern 去設計，所以，其實 TreeView Widget 會根據你塞進去的 Store (Model) 來決定該怎麼去顯示。也因此，它既可以當作 Grid 來用，也可以當作 TreeView 來用，也可以當作有 TreeView 的 Grid 來用。<br />
摸索的時候，花了不少時間，但今天打算寫這篇的時候，發現<a href="http://www.go-mono.com">Mono</a>官方網站就有 Tutorial：<a href="http://www.mono-project.com/GtkSharp_TreeView_Tutorial">GtkSharp TreeView Tutorial</a>，真的是白白浪費了摸索的時間...<br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/4596589.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/4596589.html</guid>
	<category>.Net</category>
	<pubDate>Sat, 08 Dec 2007 17:12:14 +0800</pubDate>
</item>
<item>
	<title>如何在 Ubuntu/Debian 下重新編譯 mono/monodevelop</title>
	<description><![CDATA[
			謝謝你，Dale E. Moore：[MonoDevelop] Can't keep monodevelop running
信內所提供的方法，真是相當簡單又快速，也讓我學到 apt-get 的另外一個用法：build-dep

sudo apt-get build-dep mono monodevelop
Download mono-1.2.5.2.tar.bz2&lt;http://go-mono.com/sources/mono/mono-1.2.5.2.tar.bz2&gt;and monodevelop-0.17.tar.bz2&lt;http://go-mono.com/sources/monodevelop/monodevelop-0.17.tar.bz2&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>
	<content:encoded><![CDATA[
			謝謝你，Dale E. Moore：<a href="http://lists.ximian.com/pipermail/monodevelop-list/2007-November/006985.html">[MonoDevelop] Can't keep monodevelop running</a><br />
信內所提供的方法，真是相當簡單又快速，也讓我學到 apt-get 的另外一個用法：build-dep<br />
<blockquote><br />
sudo apt-get build-dep mono monodevelop<br />
Download mono-1.2.5.2.tar.bz2&lt;http://go-mono.com/sources/mono/mono-1.2.5.2.tar.bz2&gt;and monodevelop-0.17.tar.bz2&lt;http://go-mono.com/sources/monodevelop/monodevelop-0.17.tar.bz2&gt;from http://go-mono.com/sources-stable/.<br />
<br />
bunzip2 mono-1.2.5.2.tar.bz2<br />
tar xvf mono-1.2.5.2.tar.bz2<br />
cd mono-1.2.5.2<br />
./configure --prefix=`pkg-config --variable=prefix mono`<br />
make<br />
sudo make install<br />
<br />
bunzip2 monodevelop-0.17.tar.bz2<br />
tar xvf monodevelop-0.17.tar<br />
cd monodevelop-0.17<br />
./configure --prefix=`pkg-config --variable=prefix mono`<br />
make<br />
sudo make install<br />
</blockquote><br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/4557817.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/4557817.html</guid>
	<category>.Net</category>
	<pubDate>Thu, 29 Nov 2007 12:30:26 +0800</pubDate>
</item>
<item>
	<title>.Net framework 2.0 SP1/3.0 SP1/3.5 無法安裝</title>
	<description><![CDATA[
			前一陣子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's WebLog : Automated cleanup tool to remove the .NET Framework 1.0, 1.1, 2.0, 3.0 and 3.5

		]]>
	</description>
	<content:encoded><![CDATA[
			前一陣子<a href="http://www.microsoft.com">Microsoft</a>釋出了Visual Studio 2008/.Net framework 3.5，前兩天想裝起來看看，只是怎麼裝都不行。<br />
經過與<a href="http://www.google.com">Google</a>明查暗訪的結果，都說要先移除掉先前安裝的所有 .Net frameowrk以及登錄檔(Registry)裡面的資訊，再重新安裝才行。<br />
還好，<a href="http://www.microsoft.com">Microsoft</a>的<a href="http://blogs.msdn.com/astebner/">Aaron Stebner</a>寫了一個<a href="http://blogs.msdn.com/astebner/archive/2006/05/30/611355.aspx" title="Aaron Stebner's WebLog : Automated cleanup tool to remove the .NET Framework 1.0, 1.1, 2.0, 3.0 and 3.5">工具</a>，可以幫你作掉這些麻煩事，也因為這個工具，我先移除了先前安裝的 .Net framework 3.0，再移除掉 .Net framework 2.0，接著依序安裝 .Net framework 2.0 SP1、.Net framework 3.0 SP1、.Net framework 3.5，就大功告成了。<br />
<br />
關於這個工具的文章與下載網址：<a href="http://blogs.msdn.com/astebner/archive/2006/05/30/611355.aspx">Aaron Stebner's WebLog : Automated cleanup tool to remove the .NET Framework 1.0, 1.1, 2.0, 3.0 and 3.5</a><br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/4553349.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/4553349.html</guid>
	<category>.Net</category>
	<pubDate>Wed, 28 Nov 2007 17:48:52 +0800</pubDate>
</item>
<item>
	<title>新版 mod_mono 在啟動時的警告</title>
	<description><![CDATA[
			最近在重新啟動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>
	<content:encoded><![CDATA[
			最近在重新啟動<a href="http://www.apache.org/httpd/">Apache httpd</a>時，常出現這錯誤訊息(我的環境：CentOS 4.5)：<br />
<blockquote>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.<br />
</blockquote><br />
<br />
今天早上認真地向<a href="http://www.google.com.tw">Google</a>祈禱了一下，發現有人問過了：<a href="http://lists.ximian.com/pipermail/mono-list/2007-September/thread.html#36163">[Mono-list] Errors after update....:(</a><br />
解決方法很簡單，就是打開你的 httpd.conf，確定<pre>User apache<br />
Group apache</pre><br />
在<pre>Include conf.d/*.conf</pre>之前即可。<br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/4390155.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/4390155.html</guid>
	<category>.Net</category>
	<pubDate>Tue, 30 Oct 2007 07:45:03 +0800</pubDate>
</item>
<item>
	<title>How to monorail by Generator tool(1)</title>
	<description><![CDATA[
			環境：Windows 2000/XP
需求：Subversion(或TortoiseSVNNAntMono，主要是要裡面的 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 上提供的網址(每日更新)，如：&lt;property name="castle.url" value="http://builds.castleproject.org/builds/castleproject-1.1-build_456-net-2.0-debug.zip" /&gt;；或是本地端位置 &lt;property name="castle.url" value="file://c:\download\Castle-net-2.0-debug-2007-7-30 (r4074).zip" /&gt;修改 public/web.config，第18行多了 &lt;services&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>
	<content:encoded><![CDATA[
			環境：Windows 2000/XP<br />
需求：<ul><li><a href="http://subversion.tigris.org/">Subversion</a>(或<a href="http://tortoisesvn.tigris.org/">TortoiseSVN</a></li><li><a href="http://nant.sourceforge.net">NAnt</a></li><li><a href="http://www.go-mono.com">Mono</a>，主要是要裡面的 boo</li></ul><br />
<ol><li>利用<a href="http://subversion.tigris.org/">Subversion</a>(或<a href="http://tortoisesvn.tigris.org/">TortoiseSVN</a> checkout Generator 出來，網址：<a href="http://svn.castleproject.org:8080/svn/castle/trunk/Tools/Generator/">http://svn.castleproject.org:8080/svn/castle/trunk/Tools/Generator/</a>。</li><li>進行編譯與安裝：nant install，這個步驟會將 monorail.bat 與 generator.bat 這兩個批次檔安裝到 c:\winnt 或 c:\windows 下。</li><li>切換到你的工作目錄，執行 monorail your_project，就會自動幫你產生出 your_project 這個目錄，裡面就是完整的框架。</li><li>切換到 your_project 目錄下，執行 nant setup，這個步驟會自動幫你下載官方網站上的 rc2 版本下來進行設定，如果你想要使用最新的組件，可以修改 default.build 裡面的 castle.url，將他改為<a href="http://builds.castleproject.org/cruise/index.castle">官方 build server</a> 上提供的網址(每日更新)，如：<blockquote>&lt;property name="castle.url" value="http://builds.castleproject.org/builds/castleproject-1.1-build_456-net-2.0-debug.zip" /&gt;</blockquote>；或是本地端位置 <blockquote>&lt;property name="castle.url" value="file://c:\download\Castle-net-2.0-debug-2007-7-30 (r4074).zip" /&gt;</blockquote></li><li>修改 public/web.config，第18行多了 &lt;services&gt; 將這行移除或註解掉。</li><li>將 <a href="http://www.go-mono.com">Mono</a> 目錄下的 booi.bat 複製到 your_project 目錄下，script 目錄下的批次檔都會用到，所以複製到這邊以後會比較省事。</li><li>修改 script\server.bat為如下內容，如果你不修改的話，Webdev.WebServer.exe 雖然可以順利執行，但卻會出錯。<blockquote>@booi script\server.boo %windir%\Microsoft.NET\Framework\v2.0.50727\Webdev.WebServer.exe norestart /port:8080 /path:%CD%\public</blockquote></li><li>執行 script\server，右下角會有 Webdev.WebServer.exe 的 trayicon 出現，告訴你可以用了。打開瀏覽器吧，在網址列輸入 http://localhost:8080/index.html 就可以看到畫面囉～</li></ol><br />
<br />
除了以上的步驟，產生出來的專案目錄下有個 README.TXT，你也可以好好地閱讀一下。<br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/3850251.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/3850251.html</guid>
	<category>.Net</category>
	<pubDate>Thu, 02 Aug 2007 08:00:50 +0800</pubDate>
</item>
<item>
	<title>如何使用 Mono.GetOptions？</title>
	<description><![CDATA[
			Mono.GetOptions 是做什麼的？問的好。
如果你曾經在 Linux 下開發過 console 應用程式，相信你對於getopt這個 library 應該不陌生才對。
Mono.GetOptions 就是一個類似 getopt 的組件。

這裡主要是介紹怎麼使用，下面就列出步驟：
安裝Mono。在 AssemblyInfo.cs 裡面加入：//填入簡單的用法說明，顯示 help 時會用到
[assembly: Mono.UsageComplement("[-t:param] [-o] [-h] [-v] [-u]")]
//填入關於這程式的說明，也是顯示 help 時會用到
[assembly: Mono.About("A sample about how to use Mono.GetOptions")]
//作者
[assembly: Mono.Author("your_name")]
//有錯誤時可以通報誰，可填可不填
[assembly: Mono.ReportBugsTo("your_name@your_domain.com")]
//更詳細的說明，可填可不填
[assembly: Mono.AdditionalInfo("This is a sample about how to use Mono.GetOptions.  It's only a small program.  If you want to know more about Mono.GetOptions, you can hack Mono.GetOptions source code.")]
//是屬於哪個套件，可填可不填
[assembly: Mono.IsPartOfPackage("Samples")]
然後在原來的地方應該會有這些：[assembly: AssemblyTitle("Mono.GetOptions Sample")]
[assembly: AssemblyProduct("getoptions_sample")]
[assembly: AssemblyCopyright("your_name or your_organization")]
[assembly: AssemblyVersion("1.0.*")]
請記得都填入。引用 Mono.GetOptions 組件，用SharpDevelop的話，可以很方便的選 Add mono reference。記得 using Mono.GetOptions。using Mono.GetOptions;新增一個類別，繼承 Options。using System.Collections.Generic;
class ProgramOptions : Options
{
	private string _outputFolder = "output";

	public string OutputFolder
	{
		get { return _outputFolder; }
		set { _outputFolder = value; }
	}

	private List _templateFolders;

	// 表示最多容許兩個，參數可以用 -t 或是 --template
	// 用法大致是 -t:test 或 --template:test
	[Option(2, "Template folder, default is 'default'", 't', "template")]
	public WhatToDoNext DoTemplate( string s )
	{
		//Console.WriteLine( "template={0}", s );
		_templateFolders.Add( s );
		return WhatToDoNext.GoAhead;
	}

	// 預設只容許一個，參數是 -o 或 --output
	[Option("Output folder, default is 'output'", 'o', "output")]
	public WhatToDoNext DoOutput( string s )
	{
		//Console.WriteLine( "output={0}", 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( "Template folder = {0}", s );
Console.WriteLine( "Output folder = {0}", 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>
	<content:encoded><![CDATA[
			Mono.GetOptions 是做什麼的？問的好。<br/>
如果你曾經在 Linux 下開發過 console 應用程式，相信你對於<a href="http://www.gnu.org/software/libc/manual/html_node/Getopt.html" title="Getopt - The GNU C Library">getopt</a>這個 library 應該不陌生才對。<br/>
Mono.GetOptions 就是一個類似 <a href="http://www.gnu.org/software/libc/manual/html_node/Getopt.html" title="Getopt - The GNU C Library">getopt</a> 的組件。<br/>
<br/>
這裡主要是介紹怎麼使用，下面就列出步驟：
<ol><li>安裝<a href="http://www.go-mono.com">Mono</a>。</li><li>在 AssemblyInfo.cs 裡面加入：<pre name="code" class="c#">//填入簡單的用法說明，顯示 help 時會用到
[assembly: Mono.UsageComplement("[-t:param] [-o] [-h] [-v] [-u]")]
//填入關於這程式的說明，也是顯示 help 時會用到
[assembly: Mono.About("A sample about how to use Mono.GetOptions")]
//作者
[assembly: Mono.Author("your_name")]
//有錯誤時可以通報誰，可填可不填
[assembly: Mono.ReportBugsTo("your_name@your_domain.com")]
//更詳細的說明，可填可不填
[assembly: Mono.AdditionalInfo("This is a sample about how to use Mono.GetOptions.  It's only a small program.  If you want to know more about Mono.GetOptions, you can hack Mono.GetOptions source code.")]
//是屬於哪個套件，可填可不填
[assembly: Mono.IsPartOfPackage("Samples")]
</pre>然後在原來的地方應該會有這些：<pre name="code" class="c#">[assembly: AssemblyTitle("Mono.GetOptions Sample")]
[assembly: AssemblyProduct("getoptions_sample")]
[assembly: AssemblyCopyright("your_name or your_organization")]
[assembly: AssemblyVersion("1.0.*")]
</pre>請記得都填入。</li><li>引用 Mono.GetOptions 組件，用<a href="http://www.icsharpcode.net/OpenSource/SD/">SharpDevelop</a>的話，可以很方便的選 Add mono reference。</li><li>記得 using Mono.GetOptions。<pre>using Mono.GetOptions;</pre></li><li>新增一個類別，繼承 Options。<pre name="code" class="c#">using System.Collections.Generic;
class ProgramOptions : Options
{
	private string _outputFolder = "output";

	public string OutputFolder
	{
		get { return _outputFolder; }
		set { _outputFolder = value; }
	}

	private List<string> _templateFolders;

	// 表示最多容許兩個，參數可以用 -t 或是 --template
	// 用法大致是 -t:test 或 --template:test
	[Option(2, "Template folder, default is 'default'", 't', "template")]
	public WhatToDoNext DoTemplate( string s )
	{
		//Console.WriteLine( "template={0}", s );
		_templateFolders.Add( s );
		return WhatToDoNext.GoAhead;
	}

	// 預設只容許一個，參數是 -o 或 --output
	[Option("Output folder, default is 'output'", 'o', "output")]
	public WhatToDoNext DoOutput( string s )
	{
		//Console.WriteLine( "output={0}", s );
		_outputFolder = s;
		return WhatToDoNext.GoAhead;
	}

	public ProgramOptions()
	{
		// 表示同時接受 Linux / Windows 的命令列常態用法
		this.ParsingMode = OptionsParsingMode.Both;

		_templateFolders = new List<string>();
	}
}
</pre></li><li>在 Main 裡面使用剛剛新增的類別：<pre name="code" class="c#">ProgramOptions options = new ProgramOptions(); 
options.ProcessArgs(args);
foreach( string s in options.TemplateFolders )
	Console.WriteLine( "Template folder = {0}", s );
Console.WriteLine( "Output folder = {0}", options.OutputFolder );
</pre>就這麼簡單。</li><li>Build 以後，你可以在命令列模式或是 linux 的 console 模式下試試看了～這邊我假設你編譯出來的目的檔是 your_program：<pre>#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
</pre></li></ol>
<br/>
對<a href="http://www.gnu.org/software/libc/manual/html_node/Getopt.html" title="Getopt - The GNU C Library">getopt</a>有興趣的話，可以參考<a href="http://www.cs.nctu.edu.tw/~yslin/library/linuxc/function/16.html">getopt</a>。<br/>
這是對岸同志寫的介紹，很簡短：<li><a href="http://www.cnblogs.com/shanyou/archive/2007/06/09/777562.html">Mono项目提供的一个控制台程序辅助包GetOptions - 自由、创新、研究、探索…… - 博客园</a></li><br/>
這篇也是 Tutorial，寫的很好：<a href="http://blog.pumacode.org/2006/07/24/csharp-getopts-mono-getoptions/">The PumaCode.org Blog :: GetOpt style command line processing in C# with Mono.GetOptions</a><br/>

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/3605181.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/3605181.html</guid>
	<category>.Net</category>
	<pubDate>Fri, 06 Jul 2007 14:14:54 +0800</pubDate>
</item>
<item>
	<title>如何在 CentOS 4/4.5 裡安裝 mono</title>
	<description><![CDATA[
			這裡，我假設你用 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>
	<content:encoded><![CDATA[
			這裡，我假設你用 yum 來管理你的套件。<br />
<br />
<ol><li>下載 <a href="http://www.go-mono.com/download-stable/rhel-4-i386/mono.repo">mono.repo</a> 然後放到 /etc/yum.repos.d/ (以 root 身份)</li><li>#yum update</li><li>#yum install mono-complete xsp mod_mono</li><li>完成啦!</li></ol><br />
<br />
很簡單，對吧～<br />
如果你用 Fedora Core 3/4/5 或者是 RHEL 4，你可以參考<a href="http://www.mono-project.com/Downloads">Mono 下載頁面</a>。<br />
安裝的方法跟上面所說得非常地類似。<br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/3552733.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/3552733.html</guid>
	<category>.Net</category>
	<pubDate>Fri, 29 Jun 2007 16:20:33 +0800</pubDate>
</item>
<item>
	<title>ActiveRecord 的除錯</title>
	<description><![CDATA[
			老實說，這還真令人困擾，還好官方有說明如何得到更詳細的除錯資訊：Troubleshooting :: Castle Project。
基本上，就是加上一些設定，於是NHibernate 能根據這份設定以及內部有用到的 log4net library把一些訊息丟到 log 裡面去。
靠著產出出來的 log，終於找到問題。

		]]>
	</description>
	<content:encoded><![CDATA[
			老實說，這還真令人困擾，還好官方有說明如何得到更詳細的除錯資訊：<a href="http://www.castleproject.org/activerecord/documentation/trunk/usersguide/troubleshooting.html">Troubleshooting :: Castle Project</a>。<br />
基本上，就是加上一些設定，於是<a href="http://www.hibernate.org/343.html">NHibernate</a> 能根據這份設定以及內部有用到的 <a href="http://logging.apache.org/log4net/">log4net</a> library把一些訊息丟到 log 裡面去。<br />
靠著產出出來的 log，終於找到問題。<br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/3426043.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/3426043.html</guid>
	<category>.Net</category>
	<pubDate>Thu, 07 Jun 2007 13:49:56 +0800</pubDate>
</item>
<item>
	<title>樂透下期號碼預測(3)-完結</title>
	<description><![CDATA[
			為甚麼沈寂了這麼久才寫這篇，那是因為我發現，樂透是不可預測的。其實有學過統計學的我早應該知道了。
如果你還是想試試看預測，那麼可以參考這一系列排列組合的文章，應該會很有幫助：
瓶水相逢:C# - P(n, r) 排列組合問題 - 樂多日誌瓶水相逢:C# - 產生 Permutation - P(n) 排列問題 - 樂多日誌瓶水相逢:C# - 產生 Combination - C(n, r) 組合問題 - 樂多日誌瓶水相逢:C# - 產生 Power Set - 樂多日誌

		]]>
	</description>
	<content:encoded><![CDATA[
			為甚麼沈寂了這麼久才寫這篇，那是因為我發現，樂透是不可預測的。其實有學過統計學的我早應該知道了。<br />
如果你還是想試試看預測，那麼可以參考這一系列排列組合的文章，應該會很有幫助：<br />
<ul><li><a href="http://blog.roodo.com/chhuang/archives/3198511.html">瓶水相逢:C# - P(n, r) 排列組合問題 - 樂多日誌</a></li><li><a href="http://blog.roodo.com/chhuang/archives/3198231.html">瓶水相逢:C# - 產生 Permutation - P(n) 排列問題 - 樂多日誌</a></li><li><a href="http://blog.roodo.com/chhuang/archives/3198041.html">瓶水相逢:C# - 產生 Combination - C(n, r) 組合問題 - 樂多日誌</a></li><li><a href="http://blog.roodo.com/chhuang/archives/3196737.html">瓶水相逢:C# - 產生 Power Set - 樂多日誌</a></li></ul><br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/3397425.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/3397425.html</guid>
	<category>.Net</category>
	<pubDate>Mon, 04 Jun 2007 11:49:34 +0800</pubDate>
</item>
<item>
	<title>Porting guide</title>
	<description><![CDATA[
			今天看到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>
	<content:encoded><![CDATA[
			今天看到<a href="http://jpobst.blogspot.com/">jpobst</a>的<a href="http://jpobst.blogspot.com/2007/05/porting-guide.html">這篇文章：Porting Guide</a>。<br />
他說，他上星期在<a href="http://www.go-mono.com">Mono wiki</a>上寫了一篇<a href="http://www.mono-project.com/Guide:_Porting_Winforms_Applications">Guide: Porting Winforms Applications</a>，內文提到如何將<a href="http://nclass.sourceforge.net/">NClass</a>移植到 Linux Mono 上的過程。<br />
整個移植的過程相當簡單，首先利用<a href="http://www.mono-project.com/MoMA">MoMA (Mono Migration Analyzer)</a>去分析<a href="http://nclass.sourceforge.net/">NClass</a>，得知<a href="http://nclass.sourceforge.net/">NClass</a>使用了哪些類別，而這些類別(內部的method)在<a href="http://www.go-mono.com">Mono</a>裡面是否已經被實做、有沒有使用 P/Invoke 等技術等等，接著再去補足<a href="http://www.go-mono.com">Mono</a>的類別或改寫 NClass(別忘記寄patch給原作者啊)，這樣就完成整個移植的過程。<br />
對於想把 Windows 上的 .Net 應用程式移植到 Linux 的人，這是一篇相當具有參考性的文章。<br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/3344443.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/3344443.html</guid>
	<category>.Net</category>
	<pubDate>Fri, 25 May 2007 10:33:52 +0800</pubDate>
</item>
<item>
	<title>ActiveRecord</title>
	<description><![CDATA[
			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 RecordCastle Demo App: Active Record RelationsCastle Demo App: Lazy Loading and ScopesCastle Demo App: Many To Many Relations
或是Hamilton Verissimo的系列文章：All you wanted to know about Castle ActiveRecord - Part IAll you wanted to know about Castle ActiveRecord - Part II

我覺得都寫的相當不錯。

原本官方有提供很不錯的工具：ActiveRecord Generator，可以幫你從建好的 Database schema 去產生 entity class，省去你手動寫 code 的痛苦。
只是現在因為人力不足的關係，暫時停止繼續開發。

如果你想試試看所謂的ORM，不妨試試看這個 Library，可以讓你少寫掉很多很多 code。

		]]>
	</description>
	<content:encoded><![CDATA[
			<a href="http://www.castleproject.org/activerecord/">ActiveRecord</a>是一套相當不錯的 Pattern library，主要是實做<a href="http://en.wikipedia.org/wiki/Active_record">ActiveRecord pattern</a>，底層則是<a href="http://www.nhibernate.org/">NHibernate</a>。<br />
大致的原理主要是在 Entity class 的屬性上加上 Attribute，Pattern 再根據這些資訊與設定來作 <a href="http://en.wikipedia.org/wiki/Object-relational_mapping">Object-relation mapping</a>。<br />
<br />
官方網站提供了一份很簡潔的指引：<a href="http://www.castleproject.org/activerecord/gettingstarted/index.html">Getting started with ActiveRecord</a><br />
很簡單，也很清楚，但是如果你想要更深入了解一些的話，我建議不妨參考<a href="http://www.rainsts.net/">大陸網友Yuhen</a>的這一系列文章：<ul><li><a href="http://www.rainsts.net/article.asp?id=237">[ActiveRecord] 之一：初始化和配置 - Q.yuhen</a></li><li><a href="http://www.rainsts.net/article.asp?id=238">[ActiveRecord] 之二：常用方法 - Q.yuhen</a></li><li><a href="http://www.rainsts.net/article.asp?id=239">[ActiveRecord] 之三：SessionScope - Q.yuhen</a></li><li><a href="http://www.rainsts.net/article.asp?id=486">[Castle AR] 4. CRUD - Q.yuhen</a></li><li><a href="http://www.rainsts.net/article.asp?id=487">[Castle AR] 5. Base Relations - Q.yuhen</a></li></ul><br />
或是<a href="http://www.ayende.com/Blog/Default.aspx">Oren Eini</a>的系列文章：<ul><li><a href="http://www.ayende.com/Blog/archive/7898.aspx">Castle Demo App: Getting Started With Active Record</a></li><li><a href="http://www.ayende.com/Blog/archive/7897.aspx">Castle Demo App: Active Record Relations</a></li><li><a href="http://www.ayende.com/Blog/archive/7896.aspx">Castle Demo App: Lazy Loading and Scopes</a></li><li><a href="http://www.ayende.com/Blog/archive/7891.aspx">Castle Demo App: Many To Many Relations</a></li></ul><br />
或是<a href="http://hammett.castleproject.org/">Hamilton Verissimo</a>的系列文章：<ul><li><a href="http://geekswithblogs.net/hammett/articles/76697.aspx">All you wanted to know about Castle ActiveRecord - Part I</a></li><li><a href="http://geekswithblogs.net/hammett/articles/76809.aspx">All you wanted to know about Castle ActiveRecord - Part II</a></li></ul><br />
<br />
我覺得都寫的相當不錯。<br />
<br />
原本官方有提供很不錯的工具：<a href="http://wiki.castleproject.org/index.php/ActiveRecord_Generator">ActiveRecord Generator</a>，可以幫你從建好的 Database schema 去產生 entity class，省去你手動寫 code 的痛苦。<br />
只是現在因為人力不足的關係，暫時停止繼續開發。<br />
<br />
如果你想試試看所謂的<a href="http://en.wikipedia.org/wiki/Object-relational_mapping">ORM</a>，不妨試試看這個 Library，可以讓你少寫掉很多很多 code。<br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/3338939.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/3338939.html</guid>
	<category>.Net</category>
	<pubDate>Thu, 24 May 2007 17:03:43 +0800</pubDate>
</item>
<item>
	<title>tf4mono</title>
	<description><![CDATA[
			原來早已經有非微軟官方釋出的 Team Foundation Server 的 client 端工具了～
這樣子不管是在 Linux 下或是在不想使用微軟官方 client 的情況下，都可以方便的去存取 CodePlex 的 Repository 了。

網址在這裡：tf4mono

目前只有提供 Console mode 的指令，作者希望未來可以提供 MonoDevelop 的 Add-In...

消息來源：Rope on Fire: tf4mono version 0.4.4Team Foundation for Mono - Mono Project News
		]]>
	</description>
	<content:encoded><![CDATA[
			原來早已經有非微軟官方釋出的 Team Foundation Server 的 client 端工具了～<br />
這樣子不管是在 Linux 下或是在不想使用微軟官方 client 的情況下，都可以方便的去存取 <a href="http://codeplex.com">CodePlex</a> 的 Repository 了。<br />
<br />
網址在這裡：<a href="http://code.google.com/p/tf4mono/">tf4mono</a><br />
<br />
目前只有提供 Console mode 的指令，作者希望未來可以提供 <a href="http://monodevelop.org/">MonoDevelop</a> 的 Add-In...<br />
<br />
消息來源：<ul><li><a href="http://ropeonfire.blogspot.com/2007/05/tf4mono-version-044.html">Rope on Fire: tf4mono version 0.4.4</a></li><li><a href="http://www.mono-project.com/news/archive/2007/May-21.html">Team Foundation for Mono - Mono Project News</a></li></ul>
		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/3282655.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/3282655.html</guid>
	<category>.Net</category>
	<pubDate>Mon, 21 May 2007 11:23:58 +0800</pubDate>
</item>
<item>
	<title>Visual WebGui (VWG)</title>
	<description><![CDATA[
			今天在 Mono-dev 群組上看到有人詢問是否有類似 GWT 的軟體，可以快速開發 .Net 上的 ajax 程式。
Miguel 大大回答到有這麼一套：Visual WebGui (VWG) 

有空的話，來試試看好不好用。
		]]>
	</description>
	<content:encoded><![CDATA[
			今天在 Mono-dev 群組上看到有人詢問是否有類似 GWT 的軟體，可以快速開發 .Net 上的 ajax 程式。<br />
<a href="http://tirania.org/blog/">Miguel 大大</a>回答到有這麼一套：<a href="http://www.codeplex.com/visualwebgui">Visual WebGui (VWG) </a><br />
<br />
有空的話，來試試看好不好用。
		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/3282643.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/3282643.html</guid>
	<category>.Net</category>
	<pubDate>Sun, 20 May 2007 11:19:49 +0800</pubDate>
</item>
<item>
	<title>利用 Gmail SMTP server 來寄信</title>
	<description><![CDATA[
			詳情可以參考這篇：Send E-Mail from your .NET application using your GMail Account，內文提供了 .Net 1.1/2.0 的方法。

我自己用 .Net 2，試的結果，發現有這個錯誤訊息出現："Must issue a STARTTLS command first"
Google 大神告訴我，有蠻多人詢問這個問題。
仔細研讀之後，發現是我自己忘了幫 SmtpClient 設置 EnableSsl 屬性為 true。

加上之後，又丟出 "The requested feature is not implemented."。
咦？沒實做，難道我用的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 &lt;http://www.codeproject.com/useritems/SendMailUsingGmailAccount.asp&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( "Usage: MailSharp [options] ToAddress" );
        sb.AppendLine( "\t-a File to attach." );
        sb.AppendLine( "\t-f From address" );
        sb.AppendLine( "\t-b Body message" );
        sb.AppendLine( "\t-s Subject");
        sb.AppendLine( "\t-S SMTP server host" );
        sb.AppendLine( "\t-U Username for SMTP server authentication" );
        sb.AppendLine( "\t-p Password for SMTP server authentication" );
        sb.AppendLine( "\t-l Use SSL" );
        sb.AppendLine( "\t-h Help/Usage");
        sb.AppendLine();
        sb.AppendLine( "Example:" );
        sb.AppendLine( "\tFor GMail" );
        sb.AppendLine( "\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" );

        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 &gt; 0 ) {
                for ( int i=0; i&lt;args.Length; i++ ) {
                    switch ( args[i] ) {
                    case "-S": // server host
                        i++;
                        if ( i&lt;args.Length ) {
                            client.Host = args[i];
                        } else
                            throw new Exception( "-S was specified, but no value." );
                        break;
                    case "-P": // server port
                        i++;
                        if ( i&lt;args.Length ) {
                            client.Port=Convert.ToInt32( args[i] );
                        } else
                            throw new Exception( "-P was specified, but no value." );
                        break;
                    case "-T": // timeout
                        i++;
                        if ( i&lt;args.Length ) {
                            client.Timeout = Convert.ToInt32( args[i] );
                        } else
                            throw new Exception( "-T was specified, but no value." );
                        break;
                    case "-U": // username for smtp server authentication
                        i++;
                        if ( i&lt;args.Length )
                            myCred.UserName = args[i];
                        else
                            throw new Exception( "-U was specified, but no value." );
                        break;
                    case "-p": // password for smtp server authentication
                        i++;
                        if ( i&lt;args.Length )
                            myCred.Password = args[i];
                        else
                            throw new Exception( "-p was specified, but no value." );
                        break;
                    case "-l": // use SSL
                        client.EnableSsl = true;
                        break;
                    case "-s": // subject
                        i++;	// next one is subject.
                        if ( i&lt;args.Length ) {
                            message.Subject = args[i];
                            message.SubjectEncoding = System.Text.Encoding.UTF8;
                        } else
                            throw new Exception( "-s was specified, but no value." );
                        break;
                    case "-a":	// attachment
                        i++;	// next one is attachment filename.
                        if ( i&lt;args.Length ) {
                            // Add attachment.
                            Attachment data = new Attachment( args[i], MediaTypeNames.Application.Octet);
                            message.Attachments.Add(data);
                        } else
                            throw new Exception( "-a was specified, but no value." );
                        break;
                    case "-b":	// body message.
                        i++;	// next one is body message
                        if ( i&lt;args.Length ) {
                            message.Body = args[i];
                            message.BodyEncoding =  System.Text.Encoding.UTF8;
                        } else
                            throw new Exception( "-b was specified, but no value." );
                        break;
                    case "-f":	// from address
                        i++;
                        if ( i&lt;args.Length ) {
                            // Specify the e-mail sender.
                            // Create a mailing address that includes a UTF8 character
                            // in the display name.
                            // from = new MailAddress( "someone@gmail.com", "someone", System.Text.Encoding.UTF8);
                            from = new MailAddress( args[i] );
                        } else
                            throw new Exception( "-f was specified, but no value." );
                        break;
                    case "-h":	// show help/usage
                        bShowUsage=true;
                        break;
                    default:
                        to = new MailAddress( args[i] );
                        break;
                    }
                }
            } else
                throw new Exception("No arguments.");
        } catch ( Exception ex ) {
            Console.WriteLine( ex.Message );
            bShowUsage = true;
        }

        try {
            if ( bShowUsage == true )
                throw new Exception( showUsage() );

            if ( from==null )
                throw new Exception( "Must specify from address (-f)." );

            // Set destinations for the e-mail message.
            if ( to == null )
                throw new Exception("At least, must specify to address");

            if ( client.Host == string.Empty )
                throw new Exception("Must specify SMTP Server (-S)." );

            // 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's behalf.
            //client.UseDefaultCredentials = false;
            client.Credentials = myCred;

            // Send.
            // If you need asynchronous sample, please visit the reference above.
            client.Send(message);

            Console.WriteLine("Done.");
        } catch ( Exception ex ) {
            Console.WriteLine( "Exception was raised when sending...");
            Console.WriteLine( ex.Message );
        } finally {
            // Clean up.
            message.Dispose();
        }
    }
}
}


如果你打算在 Linux 下服用的話，可以搭配這個 script，免去你每次前面都要打 mono 的麻煩。
#!/bin/sh
exec /usr/bin/mono $MONO_OPTIONS "MailSharp.exe" "$@"


		]]>
	</description>
	<content:encoded><![CDATA[
			詳情可以參考<a href="http://www.codeproject.com/useritems/SendMailUsingGmailAccount.asp">這篇：Send E-Mail from your .NET application using your GMail Account</a>，內文提供了 .Net 1.1/2.0 的方法。<br/>
<br/>
我自己用 .Net 2，試的結果，發現有這個錯誤訊息出現："Must issue a STARTTLS command first"<br/>
Google 大神告訴我，<a href="http://www.google.com.tw/search?q=%22Must+issue+a+STARTTLS+command+first%22+System.Net.Mail&amp;complete=1&amp;hl=zh-TW&amp;client=firefox&amp;rls=org.mozilla:zh-TW:official&amp;start=10&amp;sa=N">有蠻多人詢問這個問題</a>。<br/>
仔細研讀之後，發現是我自己忘了幫 SmtpClient 設置 EnableSsl 屬性為 true。<br/>
<br/>
加上之後，又丟出 "The requested feature is not implemented."。<br/>
咦？沒實做，難道我用的<a href="http://www.go-mono.com">Mono</a> 1.2.3.1還沒實做這部份？<br/>
用<a href="http://www.aisto.com/roeder/dotnet/">Reflector</a>反組譯出來看之後，果然...真的還沒實做 SSL 傳輸的部份。<br/>
希望下一版會加進去...這樣就可以在 Linux 下使用了。<br/>
以下是程式碼，它是一個命令列的程式，讓你可以指定必要的欄位後寄送郵件。
打 MailSharp -h 可以得到使用說明。
<pre>/**
 * MailSharp
 *
 * Reference:
 * 	Send E-Mail from your .NET application using your GMail Account - The Code Project - C# Programming &lt;http://www.codeproject.com/useritems/SendMailUsingGmailAccount.asp&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( "Usage: MailSharp [options] ToAddress" );
        sb.AppendLine( "\t-a File to attach." );
        sb.AppendLine( "\t-f From address" );
        sb.AppendLine( "\t-b Body message" );
        sb.AppendLine( "\t-s Subject");
        sb.AppendLine( "\t-S SMTP server host" );
        sb.AppendLine( "\t-U Username for SMTP server authentication" );
        sb.AppendLine( "\t-p Password for SMTP server authentication" );
        sb.AppendLine( "\t-l Use SSL" );
        sb.AppendLine( "\t-h Help/Usage");
        sb.AppendLine();
        sb.AppendLine( "Example:" );
        sb.AppendLine( "\tFor GMail" );
        sb.AppendLine( "\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" );

        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 &gt; 0 ) {
                for ( int i=0; i&lt;args.Length; i++ ) {
                    switch ( args[i] ) {
                    case "-S": // server host
                        i++;
                        if ( i&lt;args.Length ) {
                            client.Host = args[i];
                        } else
                            throw new Exception( "-S was specified, but no value." );
                        break;
                    case "-P": // server port
                        i++;
                        if ( i&lt;args.Length ) {
                            client.Port=Convert.ToInt32( args[i] );
                        } else
                            throw new Exception( "-P was specified, but no value." );
                        break;
                    case "-T": // timeout
                        i++;
                        if ( i&lt;args.Length ) {
                            client.Timeout = Convert.ToInt32( args[i] );
                        } else
                            throw new Exception( "-T was specified, but no value." );
                        break;
                    case "-U": // username for smtp server authentication
                        i++;
                        if ( i&lt;args.Length )
                            myCred.UserName = args[i];
                        else
                            throw new Exception( "-U was specified, but no value." );
                        break;
                    case "-p": // password for smtp server authentication
                        i++;
                        if ( i&lt;args.Length )
                            myCred.Password = args[i];
                        else
                            throw new Exception( "-p was specified, but no value." );
                        break;
                    case "-l": // use SSL
                        client.EnableSsl = true;
                        break;
                    case "-s": // subject
                        i++;	// next one is subject.
                        if ( i&lt;args.Length ) {
                            message.Subject = args[i];
                            message.SubjectEncoding = System.Text.Encoding.UTF8;
                        } else
                            throw new Exception( "-s was specified, but no value." );
                        break;
                    case "-a":	// attachment
                        i++;	// next one is attachment filename.
                        if ( i&lt;args.Length ) {
                            // Add attachment.
                            Attachment data = new Attachment( args[i], MediaTypeNames.Application.Octet);
                            message.Attachments.Add(data);
                        } else
                            throw new Exception( "-a was specified, but no value." );
                        break;
                    case "-b":	// body message.
                        i++;	// next one is body message
                        if ( i&lt;args.Length ) {
                            message.Body = args[i];
                            message.BodyEncoding =  System.Text.Encoding.UTF8;
                        } else
                            throw new Exception( "-b was specified, but no value." );
                        break;
                    case "-f":	// from address
                        i++;
                        if ( i&lt;args.Length ) {
                            // Specify the e-mail sender.
                            // Create a mailing address that includes a UTF8 character
                            // in the display name.
                            // from = new MailAddress( "someone@gmail.com", "someone", System.Text.Encoding.UTF8);
                            from = new MailAddress( args[i] );
                        } else
                            throw new Exception( "-f was specified, but no value." );
                        break;
                    case "-h":	// show help/usage
                        bShowUsage=true;
                        break;
                    default:
                        to = new MailAddress( args[i] );
                        break;
                    }
                }
            } else
                throw new Exception("No arguments.");
        } catch ( Exception ex ) {
            Console.WriteLine( ex.Message );
            bShowUsage = true;
        }

        try {
            if ( bShowUsage == true )
                throw new Exception( showUsage() );

            if ( from==null )
                throw new Exception( "Must specify from address (-f)." );

            // Set destinations for the e-mail message.
            if ( to == null )
                throw new Exception("At least, must specify to address");

            if ( client.Host == string.Empty )
                throw new Exception("Must specify SMTP Server (-S)." );

            // 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's behalf.
            //client.UseDefaultCredentials = false;
            client.Credentials = myCred;

            // Send.
            // If you need asynchronous sample, please visit the reference above.
            client.Send(message);

            Console.WriteLine("Done.");
        } catch ( Exception ex ) {
            Console.WriteLine( "Exception was raised when sending...");
            Console.WriteLine( ex.Message );
        } finally {
            // Clean up.
            message.Dispose();
        }
    }
}
}
</pre>
<br/>
如果你打算在 Linux 下服用的話，可以搭配這個 script，免去你每次前面都要打 mono 的麻煩。
<pre>#!/bin/sh
exec /usr/bin/mono $MONO_OPTIONS "MailSharp.exe" "$@"
</pre>

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/3216455.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/3216455.html</guid>
	<category>.Net</category>
	<pubDate>Thu, 10 May 2007 15:09:44 +0800</pubDate>
</item>
<item>
	<title>Mono Cecil</title>
	<description><![CDATA[
			這篇文章：Using Cecil from IronPython再次勾起我去年初看到 Mono.Cecil 時的回憶。
什麼是Mono.Cecil??以下翻譯自Nauman Leghari's Blog : Fun with IronPython and Cecil：
"Cecil 是由 Jb Evain (http://evain.net/blog/)所撰寫的類別庫，可以用來產生或注射自訂程序到以ECMA CIL撰寫的程序和類別庫。它提供了對泛型的完整支援以及對除錯資訊的部份支援。簡單的說好了，用了 Cecil，你可以載入已經存在的組件，瀏覽裡面所有的型別，即時修改它們並保存修改過的組件。"

看起來是個很神奇的東西吧～這兩篇文章介紹了如何以IronPython去使用Cecil，是很不錯的指引文章：Nauman Leghari's Blog : Fun with IronPython and CecilNauman Leghari's Blog : Fun with IronPython and Cecil (Part II)
此外也可以參考官方提供的Cecil FAQ。

		]]>
	</description>
	<content:encoded><![CDATA[
			<a href="http://evain.net/blog/articles/2007/04/03/using-cecil-from-ironpython" title="Using Cecil from IronPython">這篇文章：Using Cecil from IronPython</a>再次勾起我去年初看到 <a href="http://www.mono-project.com/Cecil">Mono.Cecil</a> 時的回憶。<br />
什麼是<a href="http://www.mono-project.com/Cecil">Mono.Cecil</a>??以下翻譯自<a href="http://weblogs.asp.net/nleghari/pages/ironpythoncecil.aspx">Nauman Leghari's Blog : Fun with IronPython and Cecil</a>：<br />
<blockquote>"Cecil 是由 Jb Evain (<a href="http://evain.net/blog/">http://evain.net/blog/</a>)所撰寫的類別庫，可以用來產生或注射自訂程序到以ECMA CIL撰寫的程序和類別庫。它提供了對泛型的完整支援以及對除錯資訊的部份支援。簡單的說好了，用了 <a href="http://www.mono-project.com/Cecil">Cecil</a>，你可以載入已經存在的組件，瀏覽裡面所有的型別，即時修改它們並保存修改過的組件。"</blockquote><br />
<br />
看起來是個很神奇的東西吧～這兩篇文章介紹了如何以<a href="http://www.codeplex.com/IronPython">IronPython</a>去使用<a href="http://www.mono-project.com/Cecil">Cecil</a>，是很不錯的指引文章：<ul><li><a href="http://weblogs.asp.net/nleghari/pages/ironpythoncecil.aspx">Nauman Leghari's Blog : Fun with IronPython and Cecil</a></li><li><a href="http://weblogs.asp.net/nleghari/archive/2007/04/02/fun-with-ironpython-and-cecil-part-ii.aspx">Nauman Leghari's Blog : Fun with IronPython and Cecil (Part II)</a></li></ul><br />
此外也可以參考官方提供的<a href="http://www.mono-project.com/Cecil:FAQ">Cecil FAQ</a>。<br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/2954581.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/2954581.html</guid>
	<category>.Net</category>
	<pubDate>Wed, 04 Apr 2007 09:55:36 +0800</pubDate>
</item>
<item>
	<title>如何存取SQLite</title>
	<description><![CDATA[
			如果你還在找SQLite的 ADO.Net driver 的話，別找了。
因為Mono就提供了一個：SQLite at Mono。

不管你是在 Windows 或是在 Linux 上，也不管你是用 Microsoft .Net Framework 或是 Mono，都可以直接拿他的 Mono.Data.SqliteClient.dll 來使用～
使用方法也很簡單：連接字串："URI=file:/path/to/file,version=3"。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 = "URI=file:SqliteTest.db";
       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 =
          "SELECT firstname, lastname " +
          "FROM employee";
       dbcmd.CommandText = sql;
       IDataReader reader = dbcmd.ExecuteReader();
       while(reader.Read()) {
            string FirstName = reader.GetString (0);
            string LastName = reader.GetString (1);
            Console.WriteLine("Name: " +
                FirstName + " " + LastName);
       }
       // clean up
       reader.Close();
       reader = null;
       dbcmd.Dispose();
       dbcmd = null;
       dbcon.Close();
       dbcon = null;
    }
}


如果你想找一個SQLite管理工具，我個人推薦使用SQLiteSpy，既小又方便而且還免安裝。

		]]>
	</description>
	<content:encoded><![CDATA[
			如果你還在找<a href="http://www.sqlite.org/">SQLite</a>的 ADO.Net driver 的話，別找了。<br/>
因為<a href="http://www.go-mono.com">Mono</a>就提供了一個：<a href="http://www.mono-project.com/SQLite">SQLite at Mono</a>。<br/>
<br/>
不管你是在 Windows 或是在 Linux 上，也不管你是用 Microsoft .Net Framework 或是 Mono，都可以直接拿他的 Mono.Data.SqliteClient.dll 來使用～<br/>
使用方法也很簡單：<ul><li>連接字串："URI=file:/path/to/file,version=3"。URI指定檔案位置，version則是指定SQLite database版本。</li><li>從使用範例可以看出，跟 .Net framework 提供的 ADO.Net driver 用法並沒有什麼差別(範例摘錄自<a href="http://www.mono-project.com/SQLite">SQLite at Mono</a>)：<pre> using System;
using System.Data;
using Mono.Data.SqliteClient;

public class Test
{
    public static void Main(string[] args)
    {
       string connectionString = "URI=file:SqliteTest.db";
       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 =
          "SELECT firstname, lastname " +
          "FROM employee";
       dbcmd.CommandText = sql;
       IDataReader reader = dbcmd.ExecuteReader();
       while(reader.Read()) {
            string FirstName = reader.GetString (0);
            string LastName = reader.GetString (1);
            Console.WriteLine("Name: " +
                FirstName + " " + LastName);
       }
       // clean up
       reader.Close();
       reader = null;
       dbcmd.Dispose();
       dbcmd = null;
       dbcon.Close();
       dbcon = null;
    }
}
</pre></li></ul>
<br/>
如果你想找一個<a href="http://www.sqlite.org/">SQLite</a>管理工具，我個人推薦使用<a href="http://www.zeitungsjunge.de/delphi/sqlitespy/">SQLiteSpy</a>，既小又方便而且還免安裝。<br/>

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/2926961.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/2926961.html</guid>
	<category>.Net</category>
	<pubDate>Thu, 29 Mar 2007 15:14:09 +0800</pubDate>
</item>
<item>
	<title>讀取網頁(4)</title>
	<description><![CDATA[
			更快的方法，就是直接利用 .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 "";
    StreamReader reader = new StreamReader(documentStream, Encoding.UTF8);
    documentStream.Position = 0;
    string documentText = reader.ReadToEnd();


		]]>
	</description>
	<content:encoded><![CDATA[
			更快的方法，就是直接利用 .Net 2.0 提供的 WebBrowser 控制項。<br />
<br />
不過，如果用這方法，有兩個缺點：<ol><li>.Net 1.1 不適用，因為 class library 沒提供。</li><li>當直接使用 DocumentText 屬性的時候，WebBrowser 沒有轉換編碼，而是直接以 ascii 傳回。</li><li>必須是 Windows form 應用程式</li></ol><br />
<br />
那麼，我們要怎麼自行轉換編碼呢？<br />
首先利用 Reflector 來反組譯一下 DocumentText 屬性，這下就可以很清楚看到他是以 StreamReader 去讀取 DocumentStream。<br />
所以當我們確信網頁的編碼是 UTF-8 時，就可以這麼寫了：<br />
<pre><br />
    Stream documentStream = webBrowser1.DocumentStream;<br />
    if (documentStream == null)<br />
        return "";<br />
    StreamReader reader = new StreamReader(documentStream, Encoding.UTF8);<br />
    documentStream.Position = 0;<br />
    string documentText = reader.ReadToEnd();<br />
</pre><br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/2922625.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/2922625.html</guid>
	<category>.Net</category>
	<pubDate>Wed, 28 Mar 2007 16:48:16 +0800</pubDate>
</item>
<item>
	<title>在 mono 上使用 Font 的一些事</title>
	<description><![CDATA[
			昨天碰到的事情，紀錄一下：
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( "AR PL Mingti2L Big5", 12, FontStyle.Regular, GraphicsUnit.Pixel, 1, false);，應該就行了。


		]]>
	</description>
	<content:encoded><![CDATA[
			昨天碰到的事情，紀錄一下：<br />
<ol><li><a href="http://www.go-mono.com" title="mono">mono</a> 1.0 類別庫裡的 Font，有一些 ctor 裡面是空的。如果你發現使用了某個 function 沒作用，或是有些問題，你可以參考一下<a href="http://www.mono-project.com/Class_Status">Mono Class Status</a>以取得類別庫實作的狀況～或者利用<a href="http://www.aisto.com/roeder/dotnet/">Reflector for .NET</a>反組譯看看，免得傻傻在那邊查了半天還不知道原因出在哪。</li><li>字型的底層是 <a href="http://www.mono-project.com/Libgdiplus">libgdiplus</a>，更底層則是<a href="http://cairographics.org/">Cairo</a>。<a href="http://cairographics.org/">Cairo</a>又再使用了<a href="http://www.freetype.org/" title="The FreeType Project">FreeType</a>函式庫(好像還有別的，不過這是主要的)。所以字型的設定是取決於fontconfig的設定：/etc/fonts/fonts.conf(用<a href="http://www.freetype.org/" title="The FreeType Project">FreeType</a>好像跟這設定沒啥關係，總之我是這樣聯想到的)，當你使用某個字型卻無法正常顯示時(例如中文)，不妨參考設定然後直接指定字型名稱：<blockquote>Font textFont = new Font( "AR PL Mingti2L Big5", 12, FontStyle.Regular, GraphicsUnit.Pixel, 1, false);</blockquote>，應該就行了。</li></ol><br />
<br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/2856341.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/2856341.html</guid>
	<category>.Net</category>
	<pubDate>Thu, 15 Mar 2007 11:47:37 +0800</pubDate>
</item>
<item>
	<title>在.Net如何產生動畫gif (animated gif)</title>
	<description><![CDATA[
			原生的 .Net framework 雖然可以產生 gif 圖檔，但卻無法產生有動畫效果的 gif 圖檔。
找了半天，本來已經萬念俱灰，想說可能要自己來寫了。
但終於還是在SourceForge.net找到合用的library：NGif。

下載以後，可以直接參考程式，使用方法很簡單～
這邊摘錄製作的方法：
&nbsp;&nbsp;&nbsp;&nbsp;/* create Gif */
&nbsp;&nbsp;&nbsp;&nbsp;//you should replace filepath
&nbsp;&nbsp;&nbsp;&nbsp;String [] imageFilePaths = new String[]{&quot;G:\\01.png&quot;}; 
&nbsp;&nbsp;&nbsp;&nbsp;String outputFilePath = &quot;G:\\test.gif&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;AnimatedGifEncoder e = new AnimatedGifEncoder();
&nbsp;&nbsp;&nbsp;&nbsp;e.Start( outputFilePath );
&nbsp;&nbsp;&nbsp;&nbsp;e.SetDelay(500);
&nbsp;&nbsp;&nbsp;&nbsp;//-1:no repeat,0:always repeat
&nbsp;&nbsp;&nbsp;&nbsp;e.SetRepeat(0);
&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0, count = imageFilePaths.Length; i &lt; count; i++ ) 
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.AddFrame( Image.FromFile( imageFilePaths[i] ) );
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;e.Finish();


NGif同時也提供解開的方法，所以你也可以將 gif 裡面的每個 frame 都個別存為獨立的圖檔。

		]]>
	</description>
	<content:encoded><![CDATA[
			原生的 .Net framework 雖然可以產生 gif 圖檔，但卻無法產生有動畫效果的 gif 圖檔。<br/>
找了半天，本來已經萬念俱灰，想說可能要自己來寫了。<br/>
但終於還是在<a href="http://sourceforge.net" title="SourceForge.net">SourceForge.net</a>找到合用的library：<a href="http://sourceforge.net/projects/ngif/" title="SourceForge.net: NGif">NGif</a>。<br/>
<br/>
下載以後，可以直接參考程式，使用方法很簡單～<br/>
這邊摘錄製作的方法：<blockquote>
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000">/* create Gif */</font><br>
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000">//you should replace filepath</font><br>
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008080">String</font> [] imageFilePaths = <font color="#0000FF">new</font> <font color="#008080">String</font>[]{<font color="#800000">&quot;G:\\01.png&quot;</font>}; <br>
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008080">String</font> outputFilePath = <font color="#800000">&quot;G:\\test.gif&quot;</font>;<br>
&nbsp;&nbsp;&nbsp;&nbsp;AnimatedGifEncoder e = <font color="#0000FF">new</font> AnimatedGifEncoder();<br>
&nbsp;&nbsp;&nbsp;&nbsp;e.Start( outputFilePath );<br>
&nbsp;&nbsp;&nbsp;&nbsp;e.SetDelay(500);<br>
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000">//-1:no repeat,0:always repeat</font><br>
&nbsp;&nbsp;&nbsp;&nbsp;e.SetRepeat(0);<br>
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000FF">for</font> (<font color="#0000FF">int</font> i = 0, count = imageFilePaths.Length; i &lt; count; i++ ) <br>
&nbsp;&nbsp;&nbsp;&nbsp;{<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.AddFrame( <font color="#008080">Image</font>.FromFile( imageFilePaths[i] ) );<br>
&nbsp;&nbsp;&nbsp;&nbsp;}<br>
&nbsp;&nbsp;&nbsp;&nbsp;e.Finish();<br>
</blockquote>
<br/>
<a href="http://sourceforge.net/projects/ngif/" title="SourceForge.net: NGif">NGif</a>同時也提供解開的方法，所以你也可以將 gif 裡面的每個 frame 都個別存為獨立的圖檔。<br/>

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/thinkingmore/archives/2851461.html</link>
	<guid>http://blog.roodo.com/thinkingmore/archives/2851461.html</guid>
	<category>.Net</category>
	<pubDate>Wed, 14 Mar 2007 15:29:41 +0800</pubDate>
</item>
</channel>
</rss>