用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 命令來啓動它,或是經過控制面板中管理工具下的服務一項來啓動相應的Windows服務程序(見圖1)。一樣,一個Windows服務程序也不能像通常的應用程序那樣被終止。由於Windows服務程序通常是沒有用戶界面的,因此你也要經過命令行工具或是下面圖中的工具來中止它,或是在系統關閉時使得Windows服務程序自動中止。由於Windows服務程序沒有用戶界面,因此基於用戶界面的API函數對其是沒有多大的意義。爲了能使一個Windows服務程序可以正常並有效的在系統環境下工做,程序員必須實現一系列的方法來完成其服務功能。Windows服務程序的應用範圍很廣,典型的Windows服務程序包含了硬件控制、應用程序監視、系統級應用、診斷、報告、Web和文件系統服務等功能。程序員

圖1數組

 p_w_picpath

 

二.建立Windows服務程序:
      在介紹如何建立Windows服務程序之前,我先向你們介紹一下.Net框架下與Windows服務相關的命名空間和其中的類庫。.Net框架大大地簡化了Windows服務程序的建立和控制過程,這要歸功於其命名空間中的功能強大的類庫。和Windows服務程序相關的命名空間涉及到如下兩個:System.ServiceProcess和System.Diagnostics。
      要建立一個最基本的Windows服務程序,咱們只須要運用.Net框架下的System.ServiceProcess命名空間以及其中的四個類:ServiceBase、ServiceInstaller、ServiceProcessInstaller以及ServiceController,其體系結構可見圖2。併發

p_w_picpath

其中ServiceBase類定義了一些可被其子類重載的函數,經過這些重載的函數,服務控制管理器就能夠控制該Windows服務程序了。這些函數包括:OnStart()、OnStop()、OnPause()以及OnContinue()等四個。並且ServiceBase類的子類還能夠重載OnCustomCommand()函數來完成一些特定的操做。經過重載以上的一些函數,咱們就完成了一個Windows服務程序的基本框架,這些函數的重載方法以下:框架

p_w_picpath

ServiceBase類還爲咱們提供了一些屬性,而這些屬性是任何Widnows服務程序所必須的。其中的ServiceName屬性指定了Windows服務的名稱,經過該名稱系統就能夠調用Windows服務了,同時其它應用程序也能夠經過該名稱來調用它的服務。而CanPauseAndContinue和CanStop屬性顧名思義就是容許暫停並恢復和容許中止的意思。
要使得一個Windows服務程序可以正常運行,咱們須要像建立通常應用程序那樣爲它建立一個程序的入口點。在Windows服務程序中,咱們也是在Main()函數中完成這個操做的。首先咱們在Main()函數中建立一個Windows服務的實例,該實例應該是ServiceBase類的某個子類的對象,而後咱們調用由基類ServiceBase類定義的一個Run()方法。然而Run()方法並不就開始了Windows服務程序,咱們必須經過前面提到的服務控制管理器調用特定的控制功能來完成Windows服務程序的啓動,也就是要等到該對象的OnStart()方法被調用時服務才真正開始運行。若是你想在一個Windows服務程序中同時啓動多個服務,那麼只要在Main()函數中定義多個ServiceBae類的子類的實例對象就能夠了,方法就是建立一個ServiceBase類的數組對象,使得其中的每一個對象對應於某個咱們已預先定義好的服務。編輯器

p_w_picpath static coid Main()ide

三.添加文件監視服務:
瞭解了Windows服務的基本體系結構和建立方法後,咱們就能夠試着往服務中添加一些實際的功能了。下面我將向你們介紹一個能監視本地文件系統的文件監視服務-FileMonitorService。該服務能根據預先設定的本地目錄路徑監視其中的文件包括子文件夾中的任何變化:文件建立、文件刪除、文件更名、文件修改。同時,該服務還爲每種變化建立了一個相對應的計數器,計數器的做用就是反映該種變化的頻度。
首先,咱們打開Visual Studio.Net,新建一個Visual C#的Windows服務的項目,如圖3所示:
圖3函數

p_w_picpath

 

      在重載Windows服務的OnStart()函數以前,咱們先給其類添加一些計數器對象,這些計數器分別對應了文件的建立、刪除、更名以及修改等變化。一旦指定目錄中的文件發生以上的某種變化,與其相對應的計數器就會自動加1。全部的這些計數器都是定義爲PerformanceCounter類型的變量的,該類是包含在System.Diagnostics命名空間中的。工具

p_w_picpath      以後咱們便在類的InitializeComponent()方法中建立以上定義的各個計數器對象並肯定其相關屬性。同時咱們將該Windows服務的名稱設置爲「FileMonitorService」,設定其便是容許暫停並恢復的又是容許中止的。測試

private void InitializeComponent()this

              {

                     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類包含全部了對應於這些變化的處理函數。

p_w_picpath

      注意其中被監視的目錄是存放在一個應用程序配置文件中的,該文件是一個XML類型的文件。這種作法的好處就是咱們沒必要從新編譯併發布該Windows服務而只要直接修改其配置文件就能夠達到更改所要監視的目錄的功能了。
當該Windows服務啓動後,一旦被監視的目錄中的文件發生某種變化,與其相對應的計數器的值便會相應的增長,方法很簡單,只要調用計數器對象的IncrementBy()便可。

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()方法,因此咱們只好將計數器中的值減去當前值來達到這個目的。

p_w_picpath       同時,由於咱們的Windows服務是容許暫停並恢復的,因此咱們還得重載OnPause()函數和OnContinue()函數,方法很簡單,只要設定前面定義的布爾值servicePaused便可。

p_w_picpath      這樣,該Windows服務的主體部分已經完成了,不過它並不有用,咱們還必須爲其添加安裝文件。安裝文件爲Windows服務的正確安裝作好了工做,它包括了一個Windows服務的安裝類,該類是重System.Configuration.Install.Installer繼承過來的。安裝類中包括了Windows服務運行所需的賬號信息,用戶名、密碼信息以及Windows服務的名稱,啓動方式等信息。

[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

 

p_w_picpath

      根據其中提示,咱們知道安裝Windows服務須要用到一個名爲InstallUtil.exe的命令行工具。而運用該工具安裝Windows服務的方法是很是簡單的,安裝該Windows服務的命令以下:

p_w_picpath

而要卸載該Windows服務,你只要輸入以下的命令便可:

p_w_picpath

Windows服務安裝成功後,它便會出如今服務控制管理器中,如圖5所示。
圖5

p_w_picpath

這樣,該文件監視的Windows服務就完成了,一旦咱們對被監視的目錄中的文件進行操做,相應的計數器就會運做,起到監視文件變化的做用。不過這個功能對於通常的用戶而言沒多大意義,然而你能夠在此基礎上添加新的功能,好比構建一個後臺的文件處理系統,一旦被監視的目錄中的文件發生某種變化,Windows服務便對其進行特定的操做,而最終用戶就沒必要去關心後臺處理程序是如何實現的了。
四.總結: 本文向你們介紹了Windows服務的一些基本概念和構建通常的Windows服務所需的方法,同時還向你們展現了一個具備文件監視功能的Windows服務程序。經過本文,讀者應該能體會到構建Windows服務並非想象中的那麼複雜,這主要還得歸功於.Net框架爲咱們所做的大量努力。同時,但願你們能在本文給出的實例的基礎上構建更加完善和更增強大的Windows服務程序。最後但願本文對你們能有很多幫助。

相關文章
相關標籤/搜索