Windows Service有著其特有的特性,在很多運用中可以發揮作用。比如長時間的,要求輪詢的等。
Windows services enable you to perform tasks that execute as different background processes. You can use Windows services to perform tasks, such as monitoring the usage of a database. A Windows service executes in its own process space until a user stops it, or the computer is shut down.
在開發之前,理解幾個概念和關鍵類:(權威解釋見MSDN,這裡是我的理解)
1. ServiceBase : 服務基礎類。所有服務繼承並實現其中的方法,即可以成為一個windows service.
You override the methods in the ServiceBase class to create a service application. The methods of this class enable you to specify the behavior of your service application.
Method
OnStart OnPause OnStop OnContinue OnShutDown OnCustomCommand OnPowerEvent(可以在電源狀態發生變化時,比如電壓降低等)
子類可以選擇性的override其中的主要方法,比如OnStart,OnStop。基本上必須重寫這個兩個方法,這樣你的類才有個性。
2. 服務安裝和服務開發:
半天都用在了服務安裝上。通過上面可以看出服務開發實際上並不是很難(我是說業務也很簡單)。然後服務安裝卻顯的很麻煩。
System.Configuration.Install.Installer類是安裝的基礎類。可以通過它來添加服務安裝的其他Installer,比如LogInstaller,PerformanceCounterInstaller等。
this.Installers.AddRange(new System.Configuration.Install.Installer[] {
this.eventLogInstaller1,
this.performanceCounterInstaller1,
this.serviceProcessInstaller1,
this.serviceInstaller1});
你可以通過這樣的代碼,也可以通過直接拖放這些組件實現。
ServiceInstaller必須制定servicename,這個名字不能和現有服務重複。
如果你添加了EventLogInstaller後,你必須小心了,它的Log和Source屬性必須被制定。如Log=Application,Souce=ServiceInstall.ServiceName。
因為這個,我搞了很久:(
繼續。。。。
你需要添加ServiceProcessInstaller,然而你需要注意它的Account屬性。它預設為User,這會在安裝服務時,彈出對話方塊資訊,要求使用者名稱和密碼。如果沒有指定正確,麻煩來了,並且你怎麼也不會想到異常來自於這裡。Exception資訊是:
在“安裝”階段發生異常。
System.ArgumentOutOfRangeException: 索引和長度必須引用該字串內的位置。
參數名: length
將它設定成LocalSystem就可以工作了.
3. ServiceController:
指定它的service名稱後,就可以通過程式來控制你的服務。這個給無介面的服務帶來了一些UI契機。
基本概念技術,進入開發,通過這個demo,實現一個簡單的郵件發送功能。
1) 繼承ServiceBase ,實現自己的服務。這個過程很簡單,vs2005整合了開發Service的項。
partial class MailService : ServiceBase{。。}
預設要求override OnStart和OnStop兩個方法。
protected override void OnStart(string[] args){} -----------這個參數還是很有意義的。比如這裡郵件清單如果是檔案,那麼位置可以在這裡指出。線程休眠時間也可以在這裡給出。
如:
if (args.Length > 0)
{
try
{
SLEEP_TIME = Convert.ToInt32(args[0]);
}
catch (Exception)
{
Console.WriteLine("Error args !");
}
}
protected override void OnStop(){}
2) 安裝服務。如果你的業務很簡單,至此已經完成了一半工作。
服務安裝,也可以通過vs2005中新添項完成。起碼要添加兩個Installer.一個是ServiceInstaller和ServiceProcessInstaller.
還可以添加EventLogInstaller和PerformanceCounterInstaller,MessageQueueInstaller
需要注意點上面已經提到了。
3) 這樣基本完成了,安裝你的服務,命令如下: InstallerUtil filename.exe
如果一切順利。你就可以在SCM(Service Control Management)上看到你的服務了。
從上面的過程可以看出。windows service本身還是很簡單的。所以有理由把更多的時間和精力用在你的業務上。這裡是郵件發送,那麼如何更好的,更方面的,更容易擴充的實現這個功能成了首要問題。
郵件配置:通過設定檔完成。
郵件發送:封裝好的SMTP郵件發送類。
郵件清單:IGetMailList
業務:根據需求判斷是否發送。
a. 配置:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<smtp deliveryMethod="Network" from="flyingchen@*****.com">
<network host="*****" port="25" defaultCredentials="true" userName="" password="" enableSsl="false"/>
</smtp>
<subject>
<content>Information</content>
</subject>
<body>
<content>
More info
</content>
</body>
</configuration>
在服務進程中依然可以通過配置改變。
b.這個自然不用多說。
c. 郵件清單來源很多。有檔案形式的,有從資料庫的,有從exchange server的,通過此介面可以屏蔽這些差異。返回給郵件發送類的就是IList<String>
d:public delegate bool NeedSend();定義這麼一個委託。根據業務需求決定是否需要發送郵件。
至此結束。測試一下,小小“攻擊”下,設定1秒發送一份到同事的郵箱。哈哈,撐爆他!