創建一個Windows Service應用程序 --------------------------------------------------------------------------------
下載本文代碼 見資源 正是由于.NET Framework的出現,才使你能夠構建出在系統重新啟動時自動運行的、無人參與的(unattended)應用程序。 by Stan Schultes 技術工具箱:VB.NET, XML, ASP Windows service應用程序曾經是C++程序員專用的領域,除非你在VB中使用了第三方工具,F在它們則成為System.ServiceProcess 命名空間下的.NET Framework類庫中的主要部分,你可以隨意使用任何.NET語言來構建它。Windows service是一種系統自動的、無人參與的程序(僅存在于Windows NT、2000和XP操作系統中),它能夠在系統啟動時開始運行。你可以通過Service Control Manager (SCM) applet或者一些特殊的service-control應用(utility)來訪問Windows service。
我將講解如何構建一個用于監控文件改變情況的Windows service。FileChangeMonitor service用于隨意地編寫事務日志(event-log)條目以及當文件在一段時間內沒有改變時發送e-mail。這種文件監控過程在用于確保需要時進行備份、正常運轉報告生成器或按時間表將文件傳送到遠程系統上時是非常有用的。FileChangeMonitor service還能夠發送顯示程序正常運行的綜合報告。
第一步是構建一個作為將來service項目起始點的Windows service程序的模板。打開Visual Studio.NET,用Windows Service模板來創建一個新的項目,將其命名為FileChangeMonitor(點此下載范例代碼)。鼠標右鍵單擊Solution Explorer(SE)中的Service1.vb文件并將其重新命名為ChangeMonitor.vb。點擊ChangeMonitor 設計界面(你會看到“To add components to your class”消息),并將其在屬性窗口(按F4顯示的窗口)中的的名字和ServiceName屬性均改為ChangeMonitor。
同樣將屬性窗口中的CanPauseAndContinue和CanShutdown屬性值設置為True。 這些屬性控制著該service程序是否能夠暫停/繼續,以及在系統關閉時是否做出響應。你將在后面使用這些事件(以及Stop事件)來保存你的service的“狀態”――即給定時間內的執行文本(execution context )。
接下來,點擊ChangeMonitor 設計窗口中的“click here to switch to code view”鏈接。在代碼窗口中,點擊左邊的加號來打開名為“Component Designer generated code”的區域。在Sub Main過程(routine)中,將ServicesToRun 賦值語句中的Service1改為ChangeMonitor: ServicesToRun = New System. _ ServiceProcess.ServiceBase() _ {New ChangeMonitor()}
右鍵單擊在SE中的FileChangeMonitor項目,選中屬性,再從StartupObject下拉列表中選擇Sub Main,F在你就可以開始構建你的項目了(通過使用Build | Build Solution菜單項)。
創建事件模板和過程 現在,在模板中加入一些事件過程(event-routine)的原型。你等一會兒可以將代碼添加到這些service事件中去以便處理 Windows service程序中的狀態變化。在代碼窗口中點擊Class Name combo box(位于代碼窗口上面左側的combo box),然后選中(Overrides)選項。在Method Name combo box中(位于代碼窗口上面右側的combo box),依次選中各項以便將過程原型(一個空程序)添加到代碼窗口中,比如:OnContinue、OnPause和OnShutdown。你必須在每個過程中的Method Name combo box中重新選擇(Overrides)選項 。
接下來就開始構建過程模板。在你需要添加代碼的ChangeMonitor.vb中創建五個子過程原型: LoadSettings()、SaveSettings()、RunCheck()、RunSummary()和StartService()。在這個類的最頂部Imports System.ServiceProcess語句的下面,通過使用Imports語句來添加其他需要用到的命名空間:Imports System.IO Imports System.Timers Imports System.Web.Mail Imports System.Reflection Imports System.Xml.Serialization
由于你的service應用程序不是一個Web項目,因此你可能需要手動將一個引用(reference)添加到Web.Mail命名空間下。右鍵單擊SE中的FileChangeMonitor項目,從彈出菜單中選擇Add Reference。在 Add Reference對話框中選擇列表中的System.Web.dll條目,單擊Select按鈕,然后點OK。
在ChangeMonitor類的頂部、Component Designer區域的前面,添加一個用于文件檢查功能的Timer對象的聲明: Private WithEvents ControlTimer As Timer
然后將下面三行代碼加到OnStart和OnContinue事件程序中: StartService() RunCheck() RunSummary()
當你的service啟動時會觸發OnStart事件,而當暫停后繼續運行時則會觸發OnContinue事件。
在Class Name combo box中選擇ControlTimer,并在Method Name combo box中選擇Elapsed。這樣就會將ControlTimer_Elapsed事件過程原型添加到項目中了。只需添加這兩個Run語句到ControlTimer_Elapsed事件過程中,然后在OnPause、OnShutdown和OnStop事件過程中添加代碼來中斷計時器(Timer)并保存設置: ControlTimer.Stop() SaveSettings()
從這個簡單的程序大綱中你可以看到用于Windows service應用程序的文件檢查功能的控制流程是如何運作的。當其中一個事件觸發時,StartService函數便會加載設置,然后運行文件和簡要檢查。你可以在計時器時間到時運行檢查程序;可以用stop或pause事件來中斷計時器以及保存設置。
在StartService過程中添加代碼來創建計時器,將時間間隔定為15秒(以毫秒值計),然后啟動它:ControlTimer = New Timer() ControlTimer.Interval = 15000 ControlTimer.AutoReset = True ControlTimer.Start()
AutoReset = True屬性設定使計時器在時間到時繼續運行。接下來,你可以在check函數運行時添加代碼來編寫Windows Application事務日志,這樣你就可以看到service正在運行: Private Sub RunCheck() EventLog.WriteEntry(ServiceName & _ " - Check", "Checking Files.") End Sub
你可以通過Windows中的Event Viewer(EV)應用程序來查看事件日志中的消息。
添加一個安裝程序(Installer) 創建service應用程序模板的最后一項工作是在項目中添加一個安裝程序。在它運行之前你需要首先注冊這個Windows service程序。切換到ChangeMonitor設計界面并打開屬性窗口(如果看不到的話可以按F4),你可以看到在屬性窗口下面有一個名為Add Installer的鏈接,點擊該鏈接后會出現一個向導來引導你將一個名為ProjectInstaller的組件添加到當前項目中。這個向導在ProjectInstaller設計界面中放置了兩個service控件:ServiceProcessInstaller和ServiceInstaller。
圖1. 設置Service屬性 點擊ServiceProcessInstaller控件并對Account屬性進行設置。你可能希望選擇LocalSystem(大多數service是運行在LocalSystem中的),但如果你喜歡,你還可以將它設置為一個用戶帳戶。點擊ServiceInstaller,將它的屬性設置為DisplayName = FileChangeMonitor、 ServiceName = ChangeMonitor以及StartType = Automatic(如果你希望通過手動啟動該service的話也可以將它設置為Manual)。
通過Build | Build Solution來構建你自己的項目,確保不存在什么錯誤,F在你就可以使用一個名為InstallUtil的Framework應用來安裝你的service了。打開命令行提示(command-prompt)窗口并執行corvars.bat文件來設置環境變量(你可以下載readme文件來了解詳細內容)。使用cd(change directory)命令將其導航到你項目中的\bin目錄下。執行以下命令來安裝你的service:> InstallUtil filechangemonitor.exe
現在你可以使用Control Panel的Administrative Tools菜單(Win2K 和WinXP操作系統)中的SCM applet來啟動、停止、暫停以及繼續運行你的FileChangeMonitor service了 (見圖1)。當你啟動這個service后就可以使用EV來查看Application事務日志中由該service生成的事件了。點擊F5刷新EV的顯示,你會看到“Check messages every 15 seconds”。你可以使用以下命令來卸載這個service(先用SCM來終止service): > InstallUtil filechangemonitor.exe /u
現在你可以保存該項目并將它作為以后service程序的一個模板。
Service以某種狀態運行(這可能是它未運行時保存的一組設定)。當service重新啟動時,你可以加載它上次運行時的狀態。一個簡便的方法是使用.NET Framework中的序列化類(serialization class),如System.Xml.Serialization命名空間下的XML序列化(你也可以選擇binary和SOAP序列化)。
用XML序列化保存設置 XML序列化是和用<Serializable()>屬性標記的類配合使用的。右鍵單擊SE中的FileChangeMonitor項目,從彈出的菜單中選擇Add | Add Class,將該類命名為CMonitor并點擊 OK。在CMonitor中添加兩個類――MonitorHeader和MonitorFile: <Serializable()> Public Class MonitorHeader Public MonitorIntSecs As Integer '<other header properties> Public Files() As MonitorFile End Class <Serializable()> Public Class MonitorFile Public Path As String '<other file properties> End Class
MonitorHeader包含控制service的設置,包括一組MonitorFile對象。MonitorFile對象中包含每個你想要檢查進度的文件的監控設置。你可以將大多數類的屬性當作Public變量來實現,因為它們只用于你的service項目中。查看范例代碼來了解該類的完整定義。你可以在ChangeMonitor 類的模塊中實現LoadSettings和SaveSettings序列化過程(見列表1)。
在用于聲明設置對象和存儲設置文件路徑的ChangeMonitor類的頂部添加該類的私有變量:Private m_MonitorControl As New _ MonitorHeader() Private m_sSettingsPath As String
在調用StartService()之前將代碼添加到OnStart過程中,來完成在service啟動之前對設置文件名進行檢測。用Reflection來找到應用程序的runtime .exe路徑,并用substitute .xml作為文件的擴展名(這兩個文件在同一目錄下): m_sSettingsPath = [Assembly]. _ GetEntryAssembly.Location. _ Replace(".exe", ".xml")
在VB.NET中assembly是一個關鍵字,因此在代碼中你必須把它用一個方括號括起來。你需要整理StartService()過程以便從設置文件中加載計時器間隔: If m_MonitorControl _ .MonitorIntervalSecs > 0 Then ControlTimer.Interval = _ Ctype(m_MonitorControl _ .MonitorIntervalSecs * 1000, Double) ControlTimer.AutoReset = True ControlTimer.Start() End If
現在,你可以實現主要的檢查函數――RunCheck了(見列表2)。RunCheck負責調用RunAlarmAction并計算出Files數組中每個文件的出現次數,該文件的NextCheck代表的是當前時間之前的時間并且自從上次檢查以后就沒有發生過改變。RunAlarmAction負責檢查AlarmAction標記、編寫事務日志,然后通過SendEmail過程來發送e-mail (見列表3)。
你可以采用類似的方法,基于MonitorHeader結構的匯總設置(summary setting)來實現RunSummary和RunSummaryAction方法,構建并測試你的Windows service應用程序。范例代碼中還包括一個名為FileChgCtl的service-control應用。它主要用于調試目的,可以將自定義命令(custom command)發送到FileChangeMonitor service中。自定義命令是一個范圍在128到255之間的整數。當Windows service應用程序中的OnCustomCommand事件觸發時你會得到自定義命令出現的通知。
你會發現service 應用程序在很多情況下是非常有用的,比如用在系統維護、監控以及其他自動的、無人照顧的操作中。Windows service通常會通過事務日志來記錄其活動情況,但正如我所介紹的,你的service也可以通過發送e-mail來方便地跟蹤其進展情況。構建Windows service應用程序的能力使你在用Windows構建有效的商務方案方面得以輕松地擴展。
關于作者: Stan Schultes 是Florida州Sarasota地區的一名Web和企業應用程序的架構師和開發人員,以及VB開發領域的MCP。Stan是VSM的一名特約編輯,定期為該雜志撰寫文章。你可以訪問Stan的網站www.vbnetexpert.com查看在線代碼演示、更新資料以及其他信息。他的e-mail地址是stan@vbnetexpert.com。
|