可插拔windows服務

來源:互聯網
上載者:User

如何?可插拔的windows服務
關於windows服務的建立相關資源很多,園子裡面也有很多這樣的文章。
整理了一下相關blog如下,
http://www.cnblogs.com/wuxilin/archive/2006/06/04/416838.html
http://www.cnblogs.com/wujm/archive/2005/05/12/154369.html
http://www.cnblogs.com/caca/archive/2005/02/25/109028.html
http://www.cnblogs.com/laiwen/archive/2005/08/21/219590.html

歸納一下步驟大概如下:
1.建立服務:
1.1我們應該建立windows服務類型的project,IDE會自動從serviceBase類繼承一個類出來,在這個類裡面有on_star和on_stop兩個方法,可以在裡面寫入啟動邏輯和停止邏輯
在設計檢視下我們可以修改service的屬性
Autolog                 是否自動寫入系統的記錄檔
CanHandlePowerEvent     服務時候接受電源事件
CanPauseAndContinue     服務是否接受暫停或繼續啟動並執行請求
CanShutdown             服務是否在運行它的電腦關閉時收到通知,以便能夠調用 OnShutDown 過程
CanStop                 服務是否接受停止啟動並執行請求
ServiceName             服務名
1.2選擇服務元件,並切換到設計模式,右鍵->Add Installer,產生安裝檔案。安裝檔案中的屬性修改可以參考下面的內容:
projectInstall參數修改Account(指定使用者還是使用本地系統使用者)
ServiceInstall參數修改:
描述名:Description,
顯示名:DisplayName,
ServiName:服務名,要和剛才建立的服務名一一對應才行
StartType:(Manual:服務安裝後,必須手動啟動.Automatic:每次電腦重新啟動時,服務都會自動啟動;Disabled:服務無法啟動)

2安裝
安裝服務要使用微軟提供的工具InstallUtil,這個工具在c:/windows/wicrosoft.net/framework/[version]中
使用InstallUtil 安裝,使用InstallUtil /u 反安裝服務

如果還有什麼可以參考剛才說的那幾個blog,ok一切都很簡單。但是如果要做為一個企業級的應用,往往會有別的情境需求,下面說一下我曾碰到的情境要求
1.我們的windows服務可能不止滿足一種商務邏輯,比如:如果你的機器安裝了oracle的話,就會有OracleService服務,我們啟動資料庫的時候可以只是啟動tns服務和OracleService服務就可以了,但是實際上啟動OracleService服務的同時會啟動好幾個服務,例如:DBWR(資料檔案寫入),LGWR(記錄檔寫入),SMON(系統監護),PMON(使用者進程監),CKPT(檢查點,同步資料檔案,記錄檔,控制檔案等)。有時為了效能的考慮,一個服務也可能要多線程的運行商務邏輯。比如一個匯入檔案的資料介面服務,如果資料量非常大就要這樣考慮。一般如果執行多個任務,可以有兩種方法:1.開多個線程;2.在一個線程中順序進行(可以加上時間控制)。我覺得這裡最靈活的方法是用.net本省的多線程支援來解決。
2.要能在不改變系統結構的情況下,可以非常快速的支援新的服務需求。這說明我們在onstar方法中不能寫入相關類的處理邏輯,必須要用某種方法解耦才行。

實現方法:
參考下面的類圖

servcive類和具體的業務實作類別解耦,我們可以使用原廠模式產生商務邏輯類,每個商務邏輯類啟動在一個新的線程中,在.net中原廠模式可以用反射非常方便的實現,這塊代碼如下:

typeInfo = node.Attributes["type"].Value;
                    Type type = Type.GetType(typeInfo);
                    IService instance = (IService)Activator.CreateInstance(type);
                    //初始化服務
                    instance.Initialize(node);
                    instanceArray.Add(instance);

                    //在新線程中運行服務,每個服務使用相同的安全上下文
                    ThreadStart ts = new ThreadStart(instance.Start);
                    Thread t = new Thread(ts);
                    t.Start();

從設定檔中讀出需要載入的商務邏輯類,執行個體化後用ThreadStart調用其中的Start方法,啟動新線程。這裡對設定檔的讀取如果要求比較高可以採用Enterprise Libary的Login block來做。
在OnStop方法中調用每個類的Stop方法,如果想對每個Stop方法非同步呼叫,可以用delegate封裝介面的Stop方法用
BeginInvoke方法實現非同步呼叫

  foreach (object o in instanceArray)
   {
    try
    {
     IService service = (IService)o;
     if (service !=null)
     {
            //非同步呼叫每個服務的stop方法來停止業務組件
      OnStopDelegate osd = new OnStopDelegate(service.Stop);
      osd.BeginInvoke(null,null);
     }
    }
    catch (Exception ex)
    {
     //
    }
   }

這樣,整個windows服務就實現了,這裡還有個額外的好處是可以熱部署,即不需要刪除已經部署的windows服務,將新的DLL覆蓋將以前的DLL覆蓋,修改*.exe.config檔案並重新啟動就可以了。其實我覺得停止服務,重新編譯部署後在啟動服務花費的時間可能比這樣還少些。

關於調試:
windows服務常用的調試方法是用調試->附加到進程的方法。
選擇顯示所有使用者進程,我們已經部署並啟動的windows服務進程就會出現,並跳到我們設定好的斷點處。但是這樣對service中的onstart部分調試比較麻煩。我還是推薦建立一個porjec做為調試用,這裡面可以寫onstart部分的代碼,代碼不多,非常方便。大家就可以象調試普通windows程式一樣調試這windows服務代碼了

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.