從Window系統托盤控制Windows服務 |
作者: 孟憲會 出自: 【孟憲會之精彩世界】 發佈日期: 2003-8-5 17:38:11 |
VB.NET有許多內建的類,可以讓我們輕鬆創建Windows服務程序,但如何輕鬆控制這些服務呢?一般是到管理工具裏面進行控制。本文將描述如何創建一個運行在系統托盤裏的程序來輕鬆控制一個服務程序。至於如何創建服務程序,可以參考.NET SDK或其它創建服務程序的文章,本文的例子利用IIS的W3SVC服務來做例子,來控制IIS的停止與啓動。
要開發這樣的程序,我們先打開Microsoft Visual Studio.NET,新建一個名爲ServiceController的解決方案,然後新建名爲WinForm的Visual Basic類型的Windows應用程序,然後把VS.NET自動創建的Form1.vb刪除掉,因爲我們創建的應用程序沒有用戶界面,我們在Sub Main運行程序。
先添加引用-.NET-System.ServiceProcess.dll,新建名爲modMain的模塊,代碼如下:
Imports System.Text Imports System.Diagnostics Imports System.ServiceProcess Public Module modMain Private WithEvents mobNotifyIcon As NotifyIcon Private WithEvents mobContextMenu As ContextMenu Private WithEvents mobTimer As Timers.Timer Private mobServiceController As ServiceController End Module上面的代碼首先引用了三個名稱空間,然後分別定義了四個變量:mobNotifyIcon將會在系統托盤裏顯示;ContextMenu顯示菜單信息;mobTimer爲定時器,原來檢查服務的狀態,以隨時變更菜單和圖標的狀態;mobServiceController表示Windows服務應用程序並允許連接到正在運行或者已停止的服務、對其進行操作或獲取有關它的信息。
由於服務程序是沒有用戶界面的,因此我們設置三種圖標標識服務的狀態,這裏做了三個簡單的圖標來標識服務的狀態:Running.ico,Paused.ico,Stopped.ico,分別如下:
下面我們就建立定時器SetUpTimer過程,通常,IIS停止或啓動的間隔爲5秒,我們就用5秒來做定時器的間隔,代碼如下:
Private Sub SetUpTimer() Try mobTimer = New Timers.Timer() With mobTimer .AutoReset = True .Interval = 5000 .Start() End With Catch obEx As Exception Throw obEx End Try End Sub下面,創建上下文菜單的過程,併爲每個菜單項添加事件處理程序:
Private Sub CreateMenu() Try mobContextMenu.MenuItems.Add(New MenuItem("停止",New EventHandler(AddressOf StopService))) mobContextMenu.MenuItems.Add(New MenuItem("暫停",New EventHandler(AddressOf PauseService))) mobContextMenu.MenuItems.Add(New MenuItem("繼續",New EventHandler(AddressOf ContinueService))) mobContextMenu.MenuItems.Add(New MenuItem("開始",New EventHandler(AddressOf StartService))) mobContextMenu.MenuItems.Add("-") mobContextMenu.MenuItems.Add(New MenuItem("關於",New EventHandler(AddressOf AboutBox))) mobContextMenu.MenuItems.Add(New MenuItem("退出",New EventHandler(AddressOf ExitController))) Catch obEx As Exception Throw obEx End Try End Sub當我們改變了服務的運行狀態時,我們應當向用戶反映這一變化,這裏用托盤的圖標不同來進行標識。當服務程序啓動時,就要先建立服務的狀態,首先GetServiceStatus過程調用ServiceController的Refresh方法,它將會刷新的ServiceController所有屬性。要準確得到服務程序的狀態,這一過程是至關重要的,下面的Select Case語句根據不同的服務程序的狀態,建立不同的菜單項和托盤圖標。
Private Sub GetServiceStatus() Try '//讀取狀態之前先進行刷新 mobServiceController.Refresh() '//變更菜單項和圖標 Select Case mobServiceController.Status() Case ServiceProcess.ServiceControllerStatus.Paused mobNotifyIcon.Icon = New Icon("Paused.ico") mobContextMenu.MenuItems(0).Enabled = False mobContextMenu.MenuItems(1).Enabled = False mobContextMenu.MenuItems(2).Enabled = True mobContextMenu.MenuItems(3).Enabled = False Case ServiceProcess.ServiceControllerStatus.Running mobNotifyIcon.Icon = New Icon("Running.ico") mobContextMenu.MenuItems(0).Enabled = True mobContextMenu.MenuItems(1).Enabled = True mobContextMenu.MenuItems(2).Enabled = False mobContextMenu.MenuItems(3).Enabled = False Case ServiceProcess.ServiceControllerStatus.Stopped mobNotifyIcon.Icon = New Icon("Stopped.ico") mobContextMenu.MenuItems(0).Enabled = False mobContextMenu.MenuItems(1).Enabled = False mobContextMenu.MenuItems(2).Enabled = False mobContextMenu.MenuItems(3).Enabled = True Case _ ServiceProcess.ServiceControllerStatus.ContinuePending, _ ServiceProcess.ServiceControllerStatus.PausePending, _ ServiceProcess.ServiceControllerStatus.StartPending, _ ServiceProcess.ServiceControllerStatus.StopPending mobNotifyIcon.Icon = New Icon("Paused.ico") mobContextMenu.MenuItems(0).Enabled = False mobContextMenu.MenuItems(1).Enabled = False mobContextMenu.MenuItems(2).Enabled = False mobContextMenu.MenuItems(3).Enabled = False End Select '//檢查“暫停”和“繼續”使用可用 If mobServiceController.CanPauseAndContinue = False Then mobContextMenu.MenuItems(1).Enabled = False mobContextMenu.MenuItems(2).Enabled = False End If Catch obEx As Exception Throw obEx End Try End Sub下面建立菜單項的事件處理程序:
'//停止服務的過程 Private Sub StopService(ByVal sender As Object, ByVal e As EventArgs) Try If mobServiceController.Status = ServiceProcess.ServiceControllerStatus.Running Then If mobServiceController.CanStop = True Then mobServiceController.Stop() End If End If Catch obEx As Exception Throw obEx End Try End Sub '//暫停服務的過程 Private Sub PauseService(ByVal sender As Object, ByVal e As EventArgs) Try If Not mobServiceController.Status = ServiceProcess.ServiceControllerStatus.Paused = True Then If mobServiceController.CanPauseAndContinue = True Then mobServiceController.Pause() End If End If Catch obEx As Exception Throw obEx End Try End Sub '//繼續服務程序的過程 Private Sub ContinueService(ByVal sender As Object, ByVal e As EventArgs) Try If mobServiceController.Status = ServiceProcess.ServiceControllerStatus.Paused = True Then If mobServiceController.CanPauseAndContinue = True Then mobServiceController.Continue() End If End If Catch obEx As Exception Throw obEx End Try End Sub '//開始服務程序的過程 Private Sub StartService(ByVal sender As Object, ByVal e As EventArgs) Try If mobServiceController.Status = ServiceProcess.ServiceControllerStatus.Stopped Then mobServiceController.Start() End If Catch obEx As Exception Throw obEx End Try End Sub '//“關於”菜單項的過程 Private Sub AboutBox(ByVal sender As Object, ByVal e As EventArgs) Try Dim obStringBuilder As New StringBuilder() With obStringBuilder .Append("Service Controller 使用例子") .Append(vbCrLf) .Append("CLR 版本:") .Append(Environment.Version.ToString) MsgBox(.ToString, MsgBoxStyle.Information) End With obStringBuilder = Nothing Catch obEx As Exception Throw obEx End Try End Sub '//退出服務程序的過程 Private Sub ExitController(ByVal sender As Object, ByVal e As EventArgs) Try mobTimer.Stop() mobTimer.Dispose() mobNotifyIcon.Visible = False mobNotifyIcon.Dispose() mobServiceController.Dispose() Application.Exit() Catch obEx As Exception Throw obEx End Try End Sub '//定時器停止 Public Sub mobTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) _ Handles mobTimer.Elapsed Try GetServiceStatus() Catch obEx As Exception Throw obEx End Try End Sub '//系統托盤圖標單擊事件 Public Sub mobNotifyIcon_Click(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles mobNotifyIcon.Click System.Diagnostics.Process.Start("IExplore.exe", "http://xml.sz.luohuedu.net/") End Sub下面就是主程序:
Public Sub Main() Try '//建立與服務程序的連接 mobServiceController = New System.ServiceProcess.ServiceController("IISAdmin") '//隱藏圖標,知道菜單項和圖標準備好以後。 mobNotifyIcon = New NotifyIcon() mobNotifyIcon.Visible = False mobContextMenu = New ContextMenu() CreateMenu() mobNotifyIcon.ContextMenu = mobContextMenu mobNotifyIcon.Text = "【孟憲會之精彩世界】" + _ Microsoft.VisualBasic.ChrW(10) + "http://xml.sz.luohuedu.net/" SetUpTimer() mobNotifyIcon.Visible = True Application.Run() Catch obEx As Exception MsgBox(obEx.Message.ToString, MsgBoxStyle.Critical) End End Try End Sub運行結果如下: