现在的位置: 首页 > 综合 > 正文

VS2005开发的Windows服务程序实例

2013年10月26日 ⁄ 综合 ⁄ 共 4727字 ⁄ 字号 评论关闭

(下面是我自己的讲义中摘取的部分) 

 

三、创建一个最简单的Windows服务程序

DEMOServiceTest

这个程序的功能很简单,就是定时的让主板的喇叭发出一个声音。

要使得一个Windows服务程序能够正常运行,我们需要像创建一般应用程序那样为它创建一个程序的入口点。在Windows服务程序中,我们也是在Main()函数中完成这个操作的。首先我们在Main()函数中创建一个Windows服务的实例,该实例应该是ServiceBase类的某个子类的对象,然后我们调用由基类ServiceBase类定义的一个Run()方法。然而Run()方法并不就开始了Windows服务程序,我们必须通过前面提到的服务控制管理器调用特定的控制功能来完成Windows服务程序的启动,也就是要等到该对象的OnStart()方法被调用时服务才真正开始运行。如果你想在一个Windows服务程序中同时启动多个服务,那么只要在Main()函数中定义多个ServiceBae类的子类的实例对象就可以了,方法就是创建一个ServiceBase类的数组对象,使得其中的每个对象对应于某个我们已预先定义好的服务。

Visual Studio .NET能够使创建一个Windows服务变成相当简单的一件事情。启动我们的演示服务程序的说明概述如下。

1)、新建一个项目,从一个可用的项目模板列表当中选择Windows服务ServiceTest。这样就创建了一个Windows服务程序的一个框架,它的名字是Service1。我们可以看到,系统自动的引用System.DiagnosticsSystem.ServiceProcess这两个命名空间。

从代码可以看到,这个类是从System.ServiceProcess.ServiceBase类继承下来的。同时,它也有一个应用程序的入口方法:Main()方法,方法中创建了一个新的服务的实例,并运行这个实例。代码如下:

ServicesToRun = new System.ServiceProcess.ServiceBase[] { new Service1() };

接下来为了使用线程,代码如下: System.ServiceProcess.ServiceBase.Run(ServicesToRun);

注意:在Main()方法中有一个ServiceBase[]的数组,它是为那些一个服务进程包含多个服务准备的。也就是说,在一个进程中,可以包含多个Windows服务。对于这个程序来说,它只有一个CareEye服务,因此完全可以把这个数组删除,而只是使用System.ServiceProcess.ServiceBase.Run(new Service1 ());一句就够了。

需要引入System.Threading命名空间,表示创建一个新的线程运行我们的Windows 服务。当然你也可以设置线程的优先等级。加上下面的一行代码:

MainThread.Priority=ThreadPriority.Lowest;// 把线程的优先级设到最低,这样不会耗用过多的系统性能。

在这里,就可以设置我们服务的一些属性,如:Name属性、CanStop属性、ServiceName属性、AutoLog属性:

我们把这个服务的Name属性改为:MyServiceTest。(这是我们程序中要访问其中的一个对象时的名字)

ServiceName属性改为:MyServiceTest1。(这是我们的服务名,我们用这个名字来安装这个服务。)

AutoLog属性:设置是否将服务的操作记录到日志中。

编译我们的程序可以看到,有一个错误:找不到Service1。我们要把new Service1()改为我们的名字:new MyServiceTest ()

 

2)、从工具箱的组件表当中拖动一个Timer对象到这个设计表面上 。因为我们要让计算机定时的发出声音,就要用一个时间控件。就要用到Timer控件。

(注意: 要确保是从组件列表而不是从Windows窗体列表当中使用Timer)

3)设置Timer属性,Enabled属性为FalseInterval属性3000毫秒。

(4)、打开Service1代码视图,找到OnStart部分,加入代码
protected override void OnStart(string[] args)

      {          this.timer1.Enabled=true;

      }

OnStop方法中加入下面的代码发停止服务:this.timer1.Enabled=false;

5)然后在timer1Elapsed事件中,添加发出声音的代码,代码如下:

引用API必须要引入命名空间:using  System.Runtime.InteropServices;

System.Runtime.InteropServices这个名称空间提供了一系列的类来对COM对象进行操作。

 

//服务真正要做的工作。(发出声音)

 

       [DllImport("kernel32.dll")]  //调用InteropServices中的一个方法,用于引入一个DLL文件。

       private  static  extern  int  Beep(int  dwFreq  ,int  dwDuration);

       private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)//达到间隔时发生。

 

       {

           //使喇叭发出声音的程序(用API)两个参数分别是: //声音频率 DWORD 、持续时间

           int  a=0X7FF; 

           int  b=500; 

           Beep(a,b);

      }

测试时必须设置Timer1Enable属性为true

Windows服务就做完了,余下的就是要测试了,但发现这个EXE运行时,虽然可以发出声音,但也会提示一个错误,它会提示你该EXE需要使用安装程序来安装服务。

看来不可能写一个程序就算是Windows服务了,还要把它注册到Windows才行。

下面我们就来讲如何注册我们的服务到Windows系统中。

 

四、添加服务安装程序


创建一个Windows服务,你必须还要把一个服务安装程序添加到你的Windows服务当中,这样就要用到.NET FramWork的一个命令行工具:InstallUtil.exe来进行安装你的服务。 

Installutil.exe:安装程序(Installer)工具,该工具允许你在一个指定的程序集中执行安装程序组件来安装和卸载服务器资源。这个工具与System.Configuration.Install 命名空间中的类联合工作。例如,在安装一个 Windows 服务时这个工具会被用到。

有些书上说,可以不添加安装类,通过命令行工具Installutil.exe就可以将开发的服务程序添加到服务管理器中,这是错误的。我们从Install的属性可以看出,只有通过Installer类,设置其中的ServiceNameDisplayName等属性,都能在服务管理器中,管理你开发的服务。如启动、停止等操作。所以,必须在你的服务中,添加一个Installer类,然后才能通过命令行工具Installutil.exe来管理你的服务了。经测试,不添加Installer类而直接用Installutil.exe来注册服务时,虽然提示安装成功,但是服务角不能进行正常的工作的。

(说明:同一个服务,在没有添加安装类时,用Installutil.exe注册时提示成功,在添加安装类后,不进行卸载的下,可再次注册该服务。但如果有安装类的服务在注册过一次后,就不能再一次进行注册了。)
1.
将这个服务程序切换到设计视图,选择项目右键/添加新项/安装程序类,将添加一个新的文件(Installer1.cs)到项目中。
2.
切换到Installer1.cs文件的设计视图。
3.
NET框架中添加
serviceInstaller1组件和serviceProcessInstaller1组件到Installer1.cs的设计视图中。

刚才讲了,serviceInstaller1中包括了进行服务安装中所共有的一些组件;serviceProcessInstaller1是注册到注册表中。


4.
设置serviceInstaller1组件的属性:
1) ServiceName =
MyServiceTest1(这是和刚才的ServiceName一样
2) StartType = Automatic(系统启动时,可以自动启动服务)

3DisplayNameMyEXEServiceTest1(这是我们在安装好服务后,在服务管理器中可以看到的名字)
5.
设置serviceProcessInstaller1组件的属性
1) Account = LocalService(表示注册和安装本机的系统中的服务)

serviceProcessInstaller类 的Account属性改为LocalSystem. 这样,不论是以哪个用户登录的系统,服务总会启动。

LocalService: 做為本機電腦上未授權使用者並將匿名認證提供給任何遠端伺服器的帳戶。

LocalSystem: 由服務控制管理員使用的帳戶,在本機電腦上具有延伸的權限,並可運作為網路上的電腦。 

NetworkService: 提供延伸的本機權限的帳戶會將電腦的認證提供給任何遠端伺服器。 

User: 由網路上的特定使用者定義的帳戶。除非您為 ServiceProcessInstaller 執行個體的 Username Password 屬性設定數值,否則為 ServiceProcessInstaller.Account 成員指定 User 會使得系統在安裝服務時提示要求有效的使用者名稱和密碼。 


6.
生成解决方案:


这时运行程序,仍然有刚才的错误提示。说明Windows Service是不能像正常的程序一样启动和运行的。

(也可以通过Service1的属性窗口下面的“添加安装程序”向导来添加一个新的安装程序。)

 

五、安装和启动Windows服务的方法

编译完后,还是无法运行,此时还需要一步,就是运行installutil.exe来安装这个服务。其安装和卸载的用法为:

installutil ServiceTest.exe
installutil /u
ServiceTest.exe

 

1、把生成的EXE文件ServiceTest.exe COPYC:/WINDOWS/Microsoft.NET/Framework/v1.1.4322目录下面。

2运行CMD命令,切换到DOS窗口中。

3、在DOS窗口中,cd C:/WINDOWS/Microsoft.NET/Framework/v1.1.4322

4、在DOS窗口中运行InstallUtil.exe ServiceTest.exe,进行安装我们刚才做的服务。

(你可以使用下面的命令来卸载我们安装的服务:

InstallUtil.exe/u  ServiceTest.exe 这样,我们的服务就从服务管理器中删除了。)

如果安装成功,就会有成功的提示了。然后在服务管理器中就可以看到我们刚才安装的服务。(有时看不到该服务,得重新启动一次系统才能在服务管理器中看到该服务。)MyMyServiceTest1,就是我们刚才设置的DisplayName属性的值。

抱歉!评论已关闭.