态度决定高度、企图决定版图、格局决定结局

导航

第一个Windows Service

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秒发送一份到同事的邮箱。哈哈,撑爆他!

posted on 2007-05-31 17:23  flyingchen  阅读(1454)  评论(3编辑  收藏  举报