建立一個Windows Service應用程式
最後更新:2017-02-28
來源:互聯網
上載者:User
window|程式|建立 建立一個Windows Service應用程式
--------------------------------------------------------------------------------
下載本文代碼
見資源
正是由於.NET Framework的出現,才使你能夠構建出在系統重新啟動時自動啟動並執行、無人蔘與的(unattended)應用程式。
by Stan Schultes
技術工具箱:VB.NET, XML, ASP
Windows service應用程式曾經是C++程式員專用的領域,除非你在VB中使用了第三方工具。現在它們則成為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。現在你就可以開始構建你的項目了(通過使用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來構建你自己的項目,確保不存在什麼錯誤。現在你就可以使用一個名為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。