`
caozuiba
  • 浏览: 902045 次
文章分类
社区版块
存档分类
最新评论

用Visual C#创建Windows服务程序

 
阅读更多
一.Windows服务介绍:

  Windows服务以前被称作NT服务,是一些运行在Windows NT、Windows 2000和Windows XP等操作系统下用户环境以外的程序。在以前,编写Windows服务程序需要程序员很强的C或C++功底。然而现在在Visual Studio.Net下,你可以运用C++或Visual C#或Visual Basic.Net很轻松的创建一个Windows服务程序。同样,你还可以运用其他任何与CLR相容的语言来创建Windows服务程序。本文就向大家介绍如何运用Visual C#来一步一步创建一个文件监视的Windows服务程序,然后介绍如何安装、测试和调试该Windows服务程序

  在介绍如何创建Windows服务程序以前,我先向大家介绍一些有关Windows服务的背景知识。一个Windows服务程序是在Windows操作系统下能完成特定功能的可执行的应用程序。Windows服务程序虽然是可执行的,但是它不像一般的可执行文件通过双击就能开始运行了,它必须有特定的启动方式。这些启动方式包括了自动启动和手动启动两种。对于自动启动的Windows服务程序,它们在Windows启动或是重启之后用户登录之前就开始执行了。只要你将相应的Windows服务程序注册到服务控制管理器(Service Control Manager)中,并将其启动类别设为自动启动就行了。而对于手动启动的Windows服务程序,你可以通过命令行工具的NET START <servicename></servicename>命令来启动它,或是通过控制面板中管理工具下的服务一项来启动相应的Windows服务程序(见图1)。同样,一个Windows服务程序也不能像一般的应用程序那样被终止。因为Windows服务程序一般是没有用户界面的,所以你也要通过命令行工具或是下面图中的工具来停止它,或是在系统关闭时使得Windows服务程序自动停止。因为Windows服务程序没有用户界面,所以基于用户界面的API函数对其是没有多大的意义。为了能使一个Windows服务程序能够正常并有效的在系统环境下工作,程序员必须实现一系列的方法来完成其服务功能。Windows服务程序的应用范围很广,典型的Windows服务程序包含了硬件控制、应用程序监视、系统级应用、诊断、报告、Web和文件系统服务等功能。

  图1



  二.创建Windows服务程序

在介绍如何创建Windows服务程序以前,我先向大家介绍一下.Net框架下与Windows服务相关的命名空间和其中的类库。.Net框架大大地简化了Windows服务程序的创建和控制过程,这要归功于其命名空间中的功能强大的类库。和Windows服务程序相关的命名空间涉及到以下两个:System.ServiceProcess和System.Diagnostics。

要创建一个最基本的Windows服务程序,我们只需要运用.Net框架下的System.ServiceProcess命名空间以及其中的四个类:ServiceBase、ServiceInstaller、ServiceProcessInstaller以及ServiceController,其体系结构可见图2。

  图2



  其中ServiceBase类定义了一些可被其子类重载的函数,通过这些重载的函数,服务控制管理器就可以控制该Windows服务程序了。这些函数包括:OnStart()、OnStop()、OnPause()以及OnContinue()等四个。而且ServiceBase类的子类还可以重载OnCustomCommand()函数来完成一些特定的操作。通过重载以上的一些函数,我们就完成了一个Windows服务程序的基本框架,这些函数的重载方法如下:

<ccid_nobr></ccid_nobr>
<ccid_code></ccid_code>protected override void OnStart(string[] args){}protected override void OnStop(){}protected override void OnPause(){}protected override void OnContinue(){}


  ServiceBase类还为我们提供了一些属性,而这些属性是任何Widnows服务程序所必须的。其中的ServiceName属性指定了Windows服务的名称,通过该名称系统就可以调用Windows服务了,同时其它应用程序也可以通过该名称来调用它的服务。而CanPauseAndContinue和CanStop属性顾名思义就是允许暂停并恢复和允许停止的意思。

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

<ccid_nobr></ccid_nobr>
<ccid_code></ccid_code>{System.ServiceProcess.ServiceBase[] MyServices;MyServices = new System.ServiceProcess.ServiceBase[] { new Service1(), new Service2() };System.ServiceProcess.ServiceBase.Run(MyServices);}


static void Main()

  三.添加文件监视服务:

  了解了Windows服务的基本体系结构和创建方法后,我们就可以试着往服务中添加一些实际的功能了。下面我将向大家介绍一个能监视本地文件系统的文件监视服务-FileMonitorService。该服务能根据预先设定的本地目录路径监视其中的文件包括子文件夹中的任何变化:文件创建、文件删除、文件改名、文件修改。同时,该服务还为每种变化创建了一个相对应的计数器,计数器的作用就是反映该种变化的频度。

  首先,我们打开Visual Studio.Net,新建一个Visual C#的Windows服务的项目,如图3所示:

  图3



  在重载Windows服务的OnStart()函数之前,我们先给其类添加一些计数器对象,这些计数器分别对应了文件的创建、删除、改名以及修改等变化。一旦指定目录中的文件发生以上的某种变化,与其相对应的计数器就会自动加1。所有的这些计数器都是定义为PerformanceCounter类型的变量的,该类是包含在System.Diagnostics命名空间中的。

<ccid_nobr></ccid_nobr>
<ccid_code></ccid_code>private System.Diagnostics.PerformanceCounter fileCreateCounter;private System.Diagnostics.PerformanceCounter fileDeleteCounter;private System.Diagnostics.PerformanceCounter fileRenameCounter;private System.Diagnostics.PerformanceCounter fileChangeCounter;


  之后我们便在类的InitializeComponent()方法中创建以上定义的各个计数器对象并确定其相关属性。同时我们将该Windows服务的名称设置为“FileMonitorService”,设定其即是允许暂停并恢复的又是允许停止的。

<ccid_nobr></ccid_nobr>
<ccid_code></ccid_code>private void InitializeComponent()              {                     this.components = new System.ComponentModel.Container();                     this.fileChangeCounter = new System.Diagnostics.PerformanceCounter();                     this.fileDeleteCounter = new System.Diagnostics.PerformanceCounter();                     this.fileRenameCounter = new System.Diagnostics.PerformanceCounter();                     this.fileCreateCounter = new System.Diagnostics.PerformanceCounter();                     fileChangeCounter.CategoryName = "File Monitor Service";                     fileDeleteCounter.CategoryName = "File Monitor Service";                     fileRenameCounter.CategoryName = "File Monitor Service";                     fileCreateCounter.CategoryName = "File Monitor Service";                     fileChangeCounter.CounterName = "Files Changed";                     fileDeleteCounter.CounterName = "Files Deleted";                     fileRenameCounter.CounterName = "Files Renamed";                     fileCreateCounter.CounterName = "Files Created";                     this.ServiceName = "FileMonitorService";                     this.CanPauseAndContinue = true;                     this.CanStop = true;                     servicePaused = false;              }


  接着就是重载OnStart()函数和OnStop()函数,OnStart()函数完成了一些必要的初始化工作。在.Net框架下,文件的监视功能可以由FileSystemWatcher类来完成,该类是包含在System.IO命名空间下的。该Windows服务所要完成的功能包括了监视文件的创建、删除、改名和修改等变化,而FileSystemWatcher类包含所有了对应于这些变化的处理函数。

<ccid_nobr></ccid_nobr>
<ccid_code></ccid_code>protected override void OnStart(string[] args)              {                          FileSystemWatcher curWatcher = new FileSystemWatcher();                     curWatcher.BeginInit();                     curWatcher.IncludeSubdirectories = true;                     curWatcher.Path =             System.Configuration.ConfigurationSettings.AppSettings               ["FileMonitorDirectory"];                     curWatcher.Changed += new FileSystemEventHandler(OnFileChanged);                     curWatcher.Created += new FileSystemEventHandler(OnFileCreated);                     curWatcher.Deleted += new FileSystemEventHandler(OnFileDeleted);                     curWatcher.Renamed += new RenamedEventHandler(OnFileRenamed);                     curWatcher.EnableRaisingEvents = true;                     curWatcher.EndInit();              }


  注意其中被监视的目录是存放在一个应用程序配置文件中的,该文件是一个XML类型的文件。这种做法的好处就是我们不必重新编译并发布该Windows服务而只要直接修改其配置文件就可以达到更改所要监视的目录的功能了。

  当该Windows服务启动后,一旦被监视的目录中的文件发生某种变化,与其相对应的计数器的值便会相应的增加,方法很简单,只要调用计数器对象的IncrementBy()即可。

<ccid_nobr></ccid_nobr>
<ccid_code></ccid_code>private void OnFileChanged(Object source, FileSystemEventArgs e)              {                     if( servicePaused == false )                     {                            fileChangeCounter.IncrementBy(1);                     }              }               private void OnFileRenamed(Object source, RenamedEventArgs e)              {                     if( servicePaused == false )                     {                            fileRenameCounter.IncrementBy(1);                     }              }	      private void OnFileCreated(Object source, FileSystemEventArgs e)              {                     if( servicePaused == false )                     {                            fileCreateCounter.IncrementBy(1);                     }              }	      private void OnFileDeleted(Object source, FileSystemEventArgs e)              {                     if( servicePaused == false )                     {                            fileDeleteCounter.IncrementBy(1);                     }              }


  OnStop()函数即是停止Windows服务的,在该Windows服务中,服务一旦停止,所有的计数器的值都应归零,但是计数器并不提供一个Reset()方法,所以我们只好将计数器中的值减去当前值来达到这个目的。

<ccid_nobr></ccid_nobr>
<ccid_code></ccid_code>protected override void OnStop()              {                     if( fileChangeCounter.RawValue != 0 )                     {                            fileChangeCounter.IncrementBy(-fileChangeCounter.RawValue);                     }                     if( fileDeleteCounter.RawValue != 0 )                     {                            fileDeleteCounter.IncrementBy(-fileDeleteCounter.RawValue);                     }                     if( fileRenameCounter.RawValue != 0 )                     {                            fileRenameCounter.IncrementBy(-fileRenameCounter.RawValue);                           }                     if( fileCreateCounter.RawValue != 0 )                     {                            fileCreateCounter.IncrementBy(-fileCreateCounter.RawValue);                     }              }


  同时,因为我们的Windows服务是允许暂停并恢复的,所以我们还得重载OnPause()函数和OnContinue()函数,方法很简单,只要设定前面定义的布尔值servicePaused即可。

<ccid_nobr></ccid_nobr>
<ccid_code></ccid_code>protected override void OnPause()              {                     servicePaused = true;              }             protected override void OnContinue()              {                     servicePaused = false;             }


  这样,该Windows服务的主体部分已经完成了,不过它并不有用,我们还必须为其添加安装文件。安装文件为Windows服务的正确安装做好了工作,它包括了一个Windows服务的安装类,该类是重System.Configuration.Install.Installer继承过来的。安装类中包括了Windows服务运行所需的帐号信息,用户名、密码信息以及Windows服务的名称,启动方式等信息。

<ccid_nobr></ccid_nobr>
<ccid_code></ccid_code>[RunInstaller(true)]       public class Installer1 : System.Configuration.Install.Installer       {              /// <summary>              /// 必需的设计器变量。              /// </summary>              private System.ComponentModel.Container components = null;              private System.ServiceProcess.ServiceProcessInstaller spInstaller;              private System.ServiceProcess.ServiceInstaller sInstaller;              public Installer1()              {                     // 该调用是设计器所必需的。                     InitializeComponent();                    // TODO: 在 InitComponent 调用后添加任何初始化              }              #region Component Designer generated code              /// <summary>              /// 设计器支持所需的方法 - 不要使用代码编辑器修改              /// 此方法的内容。              /// </summary>             private void InitializeComponent()              {                     components = new System.ComponentModel.Container();                     // 创建ServiceProcessInstaller对象和ServiceInstaller对象                     this.spInstaller =               new System.ServiceProcess.ServiceProcessInstaller();                     this.sInstaller = new System.ServiceProcess.ServiceInstaller();                     // 设定ServiceProcessInstaller对象的帐号、用户名和密码等信息                     this.spInstaller.Account =               System.ServiceProcess.ServiceAccount.LocalSystem;                     this.spInstaller.Username = null;                     this.spInstaller.Password = null;		     // 设定服务名称                     this.sInstaller.ServiceName = "FileMonitorService";		     // 设定服务的启动方式                     this.sInstaller.StartType =               System.ServiceProcess.ServiceStartMode.Automatic;                     this.Installers.AddRange(              new System.Configuration.Install.Installer[]                 {this.spInstaller, this.sInstaller });              }              #endregion       }


  同样,因为该Windows服务中运用到了计数器对象,我们也要为其添加相应的安装文件,安装文件的内容和作用与前面的类似。限于篇幅,这里就不给出相应的代码了,有兴趣的读者可以参考文后附带的源代码文件。

  到此为止,整个Windows服务已经构建完毕,不过Windows服务程序和一般的应用程序不同,它不能直接调试运行。如果你直接在IDE下试图调试运行之,就会报出如图4所示提示。

  图4



  根据其中提示,我们知道安装Windows服务需要用到一个名为InstallUtil.exe的命令行工具。而运用该工具安装Windows服务的方法是非常简单的,安装该Windows服务的命令如下:

<ccid_nobr></ccid_nobr>
<ccid_code></ccid_code>installutil FileMonitorService.exe


  而要卸载该Windows服务,你只要输入如下的命令即可:

<ccid_nobr></ccid_nobr>
<ccid_code></ccid_code>installutil /u FileMonitorService.exe


  Windows服务安装成功后,它便会出现在服务控制管理器中,如图5所示。

  图5



  这样,该文件监视的Windows服务就完成了,一旦我们对被监视的目录中的文件进行操作,相应的计数器就会运作,起到监视文件变化的作用。不过这个功能对于一般的用户而言没多大意义,然而你可以在此基础上添加新的功能,比如构建一个后台的文件处理系统,一旦被监视的目录中的文件发生某种变化,Windows服务便对其进行特定的操作,而最终用户就不必去关心后台处理程序是如何实现的了。

  四.总结:

  本文向大家介绍了Windows服务的一些基本概念和构建一般的Windows服务所需的方法,同时还向大家展示了一个具有文件监视功能的Windows服务程序。通过本文,读者应该能体会到构建Windows服务并不是想象中的那么复杂,这主要还得归功于.Net框架为我们所作的大量努力。同时,希望大家能在本文给出的实例的基础上构建更加完善和更加强大的Windows服务程序。最后希望本文对大家能有不少帮助。
分享到:
评论

相关推荐

    Visual C# 2010程序设计教程(教程PPT+源代码)

     《高等学校计算机应用规划教材:Visual C# 2010程序设计教程》详细介绍了Visual C# 2010程序设计的基础知识、基本方法和应用技巧,共分14章,主要内容包括.NET平台与Visual Studio 2010开发环境、C#语言基础及面向...

    Visual C# 2010 Express

    C#作为微软的旗舰编程语言,深受程序员喜爱,是他们编写...书中沿袭深受读者欢迎的Step by Step风格,通过丰富的练习引导读者逐步构建Windows应用程序,访问SQL Server数据库,开发 Web应用程序,创建并使用Web服务等。

    Visual C#.NET 程序设计 杨晓光清华出版社11章340页

    【部分目录】(第1章 VisuaI C#.NET集成开发环境 1.1 创建应用程序1.1.1 创建控制台应用程序1.1.2 创建Windows应用程序1.2 Visual Studio主要窗口及用法1.2.1 起始页窗口1.2.2 解决方案资源管理器对话框...

    Visual C# 2010程序设计教程PPT

    使用Visual Studio 2010创建控制台程序 "第2章 C#语法基础 " "C#基础元素 " C#中变量及数据类型 装箱与拆箱操作 数据类型转换 运算符与表达式 第3章 程序流程控制 选择结构及if,switch...

    Visual+C#+2008程序设计经典案例设计与实现.rar

    Visual+C#+2008程序设计经典案例设计与实现 第1章 Visual C#2008与窗体界面 案例1 飘动动画窗体 案例2 透明动画窗体 案例3 利用API函数实现动画窗体 案例4 闪烁动画窗体 案例5 滚动字幕动画窗体 案例6 超女卡通...

    Visual C#.NET程序设计(含书籍和源码) 李兰友 杨晓光 清华出版社,北交出版社

    1.1 创建一个Visual C#应用程序 1.2 Visual Studio .NET主要窗口及用法 1.3 Visual Studio .NET的菜单栏和工具条 本章小结 习题 第2章 C#语言基础 2.1 数据类型 2.2 表达式 2.3 程序控制语句 本章小结 习题 第3章 C#...

    Windows服务程序开发实例.pdf

    Studio.Net 下,你可以运用 C++或 Visual C#或 Visual Basic.Net 很轻松的创建一个 Windows 服务程序。同样, 你还可以运用其他任何与 CLR 相容的语言来创建 Windows 服务程序。本文就向大家介绍如何运用 Visual C#...

    Visual C#.NET技术内幕(修订版)源码

    部分则着重介绍了使用visual c# .net创建可用于web的应用程序的方 法和相关技术,介绍了soap和web服务。 本书适合于具有一定的编程经验、想要学习使用visual c# .net编程 语言的开发人员。

    Microsoft.Visual.C#.2010.Step.by.Step].(John.Sharp).中英文文字版

    创建第一个Windows Presentation Foundation应用程序构建用户界面(UI),验证数据输入管理错误和处理异常使用垃圾回收来管理内存资源使用泛型,构建新的类型,创建可重用的组件使用LINQ和ADO.NET来查询和操作数据...

    《C#创建WINDOWS服务》资料

    Windows服务以前被称作NT服务,是一些运行在Windows NT、Windows 2000和Windows XP等操作系统下用户...然而现在在Visual Studio.Net下,你可以运用C++或Visual C#或Visual Basic.Net很轻松的创建一个Windows服务程序。

    Visual C# 2010从入门到精通(周靖) pdf

    Visual C# 2010从入门到精通(周靖).pdf,本书分六部分,共二十九章,内容包括:Visual C#和Visual Studio 2010概述、理解C#语言、创建组件、操纵Windows应用程序、管理数据、使用Visual Studio 2010构建专业解决方案...

    Visual C# 2008程序设计经典案例设计与实现

    第7章 Visual C#2008与Windows系统设置 案例1 任务栏的显示与隐藏 案例2 开始按钮的显示与隐藏 案例3 动态设置系统输入法 案例4 动态设置桌面颜色 案例5 动态设置鼠标的属性 案例6 动态获取鼠标位置 案例7 ...

    Visual C#2010 从入门到精通 勘误

    书中沿袭深受读者欢迎的Step by Step风格,通过丰富的练习引导读者逐步构建Windows应用程序,访问SQL Server数据库,开发ASP.NET Web应用程序,创建并使用Web服务等。 全书共29章,结构清晰,叙述清楚。所有练习均在...

    Visual C# 2010从入门到精通(中文版)4/4

    书中沿袭深受读者欢迎的Step by Step风格,通过丰富的练习引导读者逐步构建Windows应用程序,访问SQL Server数据库,开发ASP.NET Web应用程序,创建并使用Web服务等。 全书共29章,结构清晰,叙述清楚。所有练习均在...

    C#编写Windows服务浅谈

    同样,你还可以运用其他任何与CLR相容的语言来创建Windows服务程序。本文就向大家介绍如何运用Visual C#来一步一步创建一个文件监视的Windows服务程序,然后介绍如何安装、测试和调试该Windows服务程序。

    Microsoft Visual C# 2008从入门到精通

    《Visual C# 2008从入门到精通》以最新的.NET 3.5和Visual C# 2008为基础循序渐进地介绍了从入门到深入掌握Visual C# 2008所需的各个方面,包括开发环境的配置、C#语法、Windows应用程序开发、处理文件和注册表,...

    C#windows窗体程序---计算器

    一款用Visual C#编写的计算器,基本功能全部实现了

    Visual C# 2010从入门到精通

    书中沿袭深受读者欢迎的Step by Step风格,通过丰富的练习引导读者逐步构建Windows应用程序,访问SQL Server数据库,开发ASP.NET Web应用程序,创建并使用Web服务等。, 全书共29章,结构清晰,叙述清楚。所有练习均...

    Visual C# 2008从入门到精通.pdf

     本书以最新的.NET 3.5和Visual C# 2008为基础循序渐进地介绍了从入门到深入掌握Visual C# 2008所需的各个方面,包括开发环境的配置、C#语法、Windows应用程序开发、处理文件和注册表,创建基于Web的应用程序以及...

Global site tag (gtag.js) - Google Analytics