2013年7月24日 星期三

[C#] Log4net RollingFileAppender 輸出Log依日期分資料夾

範例是在程式執行的目錄下建立[年月]資料夾(例如201307)在資料夾下在記錄每天的Log,檔名為年月日.log(例:20130724.log)
所以整個Log的結構會是

Log/201307/20130724.log
Log/201307/20130725.log
Log/201307/20130726.log
                    .
                    .
Log/201308/20130801.log


以下是設定檔的設定
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
 <file value="Log\\"/>
 <appendToFile value="true"/>
 <datePattern value="yyyyMM\\\\yyyyMMdd'.log'"/>
 <rollingStyle value="Date"/>
 <param name="StaticLogFileName" value="false" />
 <PreserveLogFileNameExtension value="true"></PreserveLogFileNameExtension>
 <layout type="log4net.Layout.PatternLayout">
  <conversionPattern value="%date [%thread] %logger - %message%newline"/>
 </layout>
</appender>

2013年6月14日 星期五

[C#] 連線到SQL的Connectionstring 使用Windows 驗證和SQL認證

Windows 驗證

 <connectionStrings>
    <add name="DBConnectionString" connectionString="Data Source=.; Database=DBName; Integrated Security=SSPI" providerName="System.Date.sqlClinet"/>

  </connectionStrings>



SQL驗證


  <connectionStrings>
    <add name="DBConnectionString" connectionString="Data Source=.;Database=DBName; User ID=LoginID; Password=LoginPassword" providerName="System.Date.sqlClinet"/>
  </connectionStrings>


這裡是以本機的DB為範例所以Data Source設為. 。如果並非機的話就設定遠端的IP及Port就可以了。格式為[IP,Port]

2013年5月8日 星期三

[C#] Windows Service 的啟動、停止和重新啟動的功能

       Windows Service除了手動到服務去做啟動、停止和重新啟動之外,也可以透過程式去做這些動作。程式碼如下:


        /// <summary>
        /// 啟動服務。
        /// </summary>
        /// <param name="serviceName">服務名稱。</param>
        /// <param name="timeoutMilliseconds">其指定等候服務到達指定之狀態的時間長度。</param>
        /// <returns>執行結果成功或失敗。</returns>
        public static bool StartService(string serviceName, int timeoutMilliseconds)
        {
            bool processResult = false;
            ServiceController service = new ServiceController(serviceName);
            try
            {
                TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
                service.Start();
                service.WaitForStatus(ServiceControllerStatus.Running, timeout);
                processResult = true;
            }
            catch (Exception e)
            {
                processResult = false;
            }
            return processResult;
        }

        /// <summary>
        /// 停止服務。
        /// </summary>
        /// <param name="serviceName">服務名稱。</param>
        /// <param name="timeoutMilliseconds">其指定等候服務到達指定之狀態的時間長度。</param>
        /// <returns>執行結果成功或失敗。</returns>
        public static bool StopService(string serviceName, int timeoutMilliseconds)
        {
            bool processResult = false;
            ServiceController service = new ServiceController(serviceName);
            try
            {
                TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
                service.Stop();
                service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
                processResult = true;
            }
            catch (Exception e)
            {
                processResult = false;
            }
            return processResult;
        }

        /// <summary>
        /// 重新啟動服務。
        /// </summary>
        /// <param name="serviceName">服務名稱。</param>
        /// <param name="timeoutMilliseconds">其指定等候服務到達指定之狀態的時間長度。</param>
        /// <returns>執行結果成功或失敗。</returns>
        public static bool RestartService(string serviceName, int timeoutMilliseconds)
        {
            bool processResult = false;
            ServiceController service = new ServiceController(serviceName);
            try
            {
                int millisec1 = Environment.TickCount;
                TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
                service.Stop();
                service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
                // count the rest of the timeout
                int millisec2 = Environment.TickCount;
                timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds - (millisec2 - millisec1));
                service.Start();
                service.WaitForStatus(ServiceControllerStatus.Running, timeout);
                processResult = true;
            }
            catch (Exception e)
            {
                processResult = false;
            }
            return processResult;
        }

2013年4月19日 星期五

Regular Expression (RegExp)

        Regular Expression( 以下筆者就簡稱為RegExp)是使用一組字串描述規則,來找符合這個規刖的字串。以一個簡單的例子來說,如果要找一個以AS3開頭的字串的話,就可以寫成^AS3來找到所有以AS3開頭的字串囉。像這種表達規則通常稱為pattern

        本文就簡短的說明一下幾個常見的字元意義
  • ^ 寫在 pattern 第一個位置時,表示其後一符號必須出現在字串開頭的位置。寫在 pattern 中間位置時則為否定之意,表示字串中不可有 ^ 之後一符號的內容。
  • $寫在 pattern 最後一個位置時,表示其前一符號必須出現在字串尾端的位置
  • *表示字串中有 0 到無數個其前一符號的內容。
  • +表示字串中有 1 到無數個其前一符號的內容(至少有一個)。
  • ?表示字串中有 0 到 1個其前一符號的內容。
  • { }表示前一符號在字串中的重覆次數。例如A{2} 表示 'A' 重覆兩次 (即 'AA') ;A{2,}表示字串含有 2 到無數多個 'A' ;A{2,5} 表示含有 2 到 5 個 'A' 。
  • . 表示一個任意字元。
  • [ ]表示字串含有括號中任一字元的內容。可以 - 表示一組連續字元,例如[A-Z]。注意, [] 僅代表一個字元,例如 [ABC]表示 'a' 或 'b' 或 'c' ,而不是 'abc' 
  • \:跳脫字元,例如要表示字串中含有 '/' 字元時,就必須寫成\/
  • |「或」意,字串中含有 '|' 之前一符號或後一符號的內容。例如image\.(jpg|png) 表示 'image.jpg' 或 'image.png' 。通常會用 () 括住 '|' 的前後符號。
  • \d表示任何一個數字,意同 [0-9] 。
  • \D表示任何一個非數字,意同 [^0-9] 。

如果想試試這個功能的,也有網頁版的可以使用

以下為常用的正則表達式
  • 網址:[a-zA-z]+://[^\s]*
  • IP Address:((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)
  • 時間(小時:分鐘 24小時制):((1|0?)[0-9]|2[0-3]):([0-5][0-9])
  • E-mail:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
  • 日期(年-月-日)(\d{4}|\d{2})-((0?([1-9]))|(1[1|2]))-((0?[1-9])|([12]([1-9]))|(3[0|1]))
  • 日期(月/日/年):((0?[1-9]{1})|(1[1|2]))/(0?[1-9]|([12][1-9])|(3[0|1]))/(\d{4}|\d{2})
  • 正整數:[0-9]*[1-9][0-9]*
  • 非負整數(正整數或零):\d+
  • 負整數:-[0-9]*[1-9][0-9]*
  • 整數:-?\d+
  • 小數:(-?\d+)(\.\d+)?

其它相關的學習資源
http://blog.miniasp.com/post/2008/03/23/Regular-Expression-Regex-Learning-Resources.aspx

[System] 註冊/刪除 Service (使用Command Line)

註冊Windows Service:
        在Command Line下輸入            
C:\Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe ServiceFilePath

ServiceFilePath為實際的服務檔路徑。例:C:\ServiceFile.exe



刪除Windows Service:
        在Command Line下輸入
sc delete ServiceName

ServiceName為服務實際的名稱




取得服務實際的名稱:
        在Command Line下輸入
services.msc

會跳出一個服務的視窗,在想要取得服務名稱的服務上按右鍵後選取內容,就可以在一般的標籤上看到服務名稱了。

如下圖紅色底線所標記












[C#] Windows Service 啟動失敗

        最近在把Console的程式改寫成Windows Service,發現如果在ServiceBase的建構子如果有寫到需要等待的動作才能繼續往下執行程式碼的話。服務就會無法被啟動。

        舉個例子來說明,如果在建構子有以下程式
_TcpListener.AcceptTcpClient()

等待Client的連入,那就會造成服務無沒被啟動。

而解決的方式就是把同步改成非同步的方式來等待Client連入
_TcpListener.BeginAcceptSocket(new AsyncCallback(Accept_Completed), _TcpListener);


後來,我在建構子寫一個空的while(true){}的迴圈來做測試,服務一樣也無法被啟動。

像這種情況下,下指令移除服務,服務是沒有辦法被移除乾淨的。必需要重開機或者登出再登入服務才會真正被移除。



5/6補充:
    在建構子寫AcceptTcpClient()本身就是一個不好的寫法。其實在繼承ServiceBase的類別中去覆寫OnStart(string[] args)的方法,再把原本寫在建構子的程式碼搬到覆寫的方法中就可以了。這個方法會在Service啟動時被呼叫,所以即使是寫_TcpListener.AcceptTcpClient()也不會有任何問題喔!

2013年4月10日 星期三

[C#] abstruct 和 virtual的差別

abstract(抽象方法)和virtual(虛擬方法)主要都是用在父類別中

主要差異在於abstract類似介面(interface)沒有實作為空的方法而其子類別必需複寫(override)實作

而virtual的方法,其子類別就不一定要複寫(override)

2013年3月30日 星期六

[SQL] @TempTable、#TempTable及##TempTable的差異


變數宣告使用DECLARE陳述式宣告
例如
DECLARE @TableName TABLE(
columnName INT
)

此宣告方式是把變數記在記憶體中,執行速度也比較快。適合處理比較小的資料量。



暫存表(Temporary Tables)的表示為
CREATE TABLE #TableName(
columnName INT
)

此暫存表把資料記在硬碟,適合資料量大的處理
在同一個session才能存取到此暫存表
在session關閉時,table會自動被drop,但是最好還是自己下指令drop,不要讓系統自動回收




全域暫存表(Global Temporary Tables)的表示為
CREATE TABLE ##TableName(
columnName INT
)

也就是說這個Table在其它Session有可以被存取到

2013年3月29日 星期五

TeamCity的安裝


安裝說明的部分筆者以Windows的平台來做說明。

首先,先到官方網站下載安裝檔。















下載完成後開始安裝





















選擇安裝路徑






















選擇安裝的元件(預設是安裝Server及Build Agent)
註:如果要把Build Agent裝在另一台機器上的話,可以選擇不安裝。





















選擇設定檔安裝的路徑(此資料夾會被設定為隱藏)
























預設的Server Port為80,如果80 Port 被其它程式使用的話,就會改為8080





















Build Agent 的屬性設定(如果Port不是80Port的話,ServerUrl就會改為http://localhost:8080




選Server的服務帳號




















選TeamCity Agent的服務帳號





















設定啟動的服務





















啟動完成後會開啟第一次執行的頁面。按下Proceed按鈕來初始化。















初始化完成後會要使用者接受使用者授權頁面























接受後會要求創造Administrator的帳號跟密碼
















創造後便可以登入進行專案的設定了!





返回TeamCity目錄

TeamCity Catalog

1.TeamCity 的安裝

2.專案的建立及設定

3.安裝 Build Agent

4.自動打包NuGet及發布

5.安裝Plugin - StyleCop

6.使用NUnit

7.TeamCity Gadget




2013年3月11日 星期一

計算廣播IP


廣播IP為網段中最後一個IP,也可以透過運算取得。
由mask做not的運算,其值再跟IP做OR的運算取得的值即為廣播IP!

拿個範例來說

假設本機取得的IP為10.9.64.88,遮罩為255.255.252.0



1. MASK:                         11111111.11111111.11111100.00000000
2. MASK做NOT運算 :        00000000.00000000.00000011.11111111
3. IP  :                              00001010.00001000.01000000.01011000
廣播IP(2跟3做OR運算):      00001010.00001000.01000011.11111111


所以廣播IP為:10.8.67.255



如需更多延申閱讀可以參考: http://www.study-area.org/network/network_ip_addr.htm