初めて作る.NET WindowsサービスVisual Studio Magazine(6/7 ページ)

» 2005年02月01日 18時49分 公開
[Doug Thews,FTPOnline]

モニタリング対象となるサンプルアプリケーションを作成する

 SecurityControllerプロジェクトは、.NETのWindowsフォームとして構成した単純なデスクトップアプリケーションで、AppMonitorモニタリングサービスの動作を確かめるために用いるものだ。

 この架空のセキュリティコントロールアプリケーションでは、先に作成したMonitorWrapperクラスを参照設定することで、セキュリティイベントに関連付けられたコマンドをサービスに向けて送信する。さらにServiceControllerオブジェクトを使ってWindowsサービスをどのように制御するのかを示すため、アプリケーションにはAppMonitorサービスを開始したり停止したりするボタンも用意した(リスト3)。

リスト3■ServiceControllerオブジェクトを使ってWindowsサービスを制御する。サンプルのセキュリティコントロールアプリケーションでは、AppMonitorサービスにコマンドを送信するのにMonitorWrapperクラスを利用する。また、ServiceControllerオブジェクトを使ってAppMonitorサービスの状態を制御する
Private Sub btnOpenGateA_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) _
Handles btnOpenGateA.Click
SendMonitorCommand _
(MonitorWrapper.MonitorWrapper. _
MonitorCode.MON_GATE_A_OPEN)
End Sub

Private Sub btnOpenGateB_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) _
Handles btnOpenGateB.Click
SendMonitorCommand _
(MonitorWrapper.MonitorWrapper. _
MonitorCode.MON_GATE_B_OPEN)
End Sub

Private Sub btnFireAlarmZoneA_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) _
Handles btnFireAlarmZoneA.Click
SendMonitorCommand _
(MonitorWrapper.MonitorWrapper. _
MonitorCode.MON_FIREALARM_A)
End Sub

Private Sub btnSprinklerZoneA_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) _
Handles btnSprinklerZoneA.Click
SendMonitorCommand _
(MonitorWrapper.MonitorWrapper. _
MonitorCode.MON_SPRINKLER_A)
End Sub

Private Sub btnStartService_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) _
Handles btnStartService.Click
' サービスを検索する
Dim objServiceController As New _
ServiceController("AppMonitor", ".")

'サービスが有効かどうか
If (objServiceController Is Nothing) Then
MessageBox.Show _
("Could Not Find AppMonitor Service On This Machine")
Return
End If

' サービスが停止しているかどうか
If (objServiceController.Status = _
ServiceControllerStatus.Stopped) Then
' サービスを開始する
Try
objServiceController.Start()
' サービスが開始するまで待つ(10秒)
objServiceController.WaitForStatus( _
ServiceControllerStatus.Running, _
New TimeSpan(0, 0, 10))
MessageBox.Show( _
"AppMonitor Service Started: Status = " + _
objServiceController.Status.ToString)
Catch ex As Exception
MessageBox.Show( _
"Unable To Start AppMonitor Service")
End Try
Else
' サービスが停止されていない
MessageBox.Show _
("AppMonitor Service Wasn't Stopped - " & _
"Unable To Start It")
End If
End Sub

Private Sub btnStopService_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) _
Handles btnStopService.Click
' サービスを検索する
Dim objServiceController As New _
ServiceController("AppMonitor", ".")

' サービスが有効かどうか
If (objServiceController Is Nothing) Then
MessageBox.Show _
("Could Not Find AppMonitor Service On This Machine")
Return
End If

' サービスが開始しているかどうか
If (objServiceController.Status = _
ServiceControllerStatus.Running) Then
' サービスを停止する
Try
objServiceController.Stop()
' サービスが停止するまで待つ(10秒)
objServiceController.WaitForStatus( _
ServiceControllerStatus.Stopped, _
New TimeSpan(0, 0, 10))
MessageBox.Show( _
"AppMonitor Service Stopped: Status = " + _
objServiceController.Status.ToString)
Catch ex As Exception
MessageBox.Show( _
"Unable To Stop AppMonitor Service")
End Try
Else
' サービスが開始されていない
MessageBox.Show _
("AppMonitor Service Wasn't Started - " & _
"Unable To Stop It")
End If
End Sub

Private Sub SendMonitorCommand(ByVal cmd As _
MonitorWrapper.MonitorWrapper.MonitorCode)
Dim rc As MonitorWrapper.MonitorWrapper.MonitorRC
rc = MonitorWrapper.MonitorWrapper.MonitorThis( _
cmd)
Select Case rc
Case MonitorWrapper.MonitorWrapper. _
MonitorRC.RC_NOSERVICE
MessageBox.Show( _
"AppMonitor Service Not Found")
Case MonitorWrapper.MonitorWrapper. _
MonitorRC.RC_SERVICECOMMANDFAIL
MessageBox.Show( _
"Error Sending Command to Service")
Case MonitorWrapper.MonitorWrapper. _
MonitorRC.RC_SERVICESTOPPED
MessageBox.Show( _
"Unable to Send Command - Service Stopped")
Case MonitorWrapper.MonitorWrapper. _
MonitorRC.RC_SUCCESS
End Select
End Sub

 上のコードを見ると分かるように、コマンドは(MonitorWrapperクラスに備わる)MonitorThisメソッドを通じて、AppMonitorサービスに送られる。[start]や[stop]のボタンを設けて、AppMonitorサービスを開始したり停止したりするコードを加えることもできる。先に説明したように、サービスはServiceControllerオブジェクトを通じて制御できるのだ。

 サービスにコマンドを送信することと、サービスの状態を変更することとの唯一の違いは、サービスの開始や停止は非同期にしなければならないという点だけだ。

 また、ServiceControllerオブジェクトのStartメソッドを呼び出すだけでも、サービスを開始できる。しかしそれでは、サービスが開始されたということが保証されない。そこでStartメソッドを呼び出した後に、WaitForStatusメソッドを呼び出して、望んだ状態にステータスが変化するまで、指定した時間(時間を省略した場合は永遠に)待つ必要がある。

 WaitForStatusメソッドがタイムアウトになったときには例外が発生する。この例外はcatchする必要がある。

 開始と同様にして、停止、一時停止、再開も処理できるのだ。Windowsサービスのデバッグは、外部プロセスのデバッグとよく似ている。

 統合開発環境の[ツール]メニューの[デバッグプロセス]コマンドから、実行中のWindowsサービスにアタッチ可能だ。統合開発環境のコードビューでブレークポイントを設定し、普通のアプリケーションと同じようにデバッグができる。

 また、Windowsサービスをデバッグする時には、「生存する」プロセスをデバッグしているという点に留意してほしい。ブレークポイントに到達した場合には、マシン上のサービスは停止し、ほかのいかなるイベントにも応答を返さなくなる。そのため、プロセスを再開することなく統合開発環境のデバッガを終了してしまうとサービスが停止状態に戻り、不安定な状態に陥る。さて簡単なモニタリングサービスを配置したところで、このモデルをどのようにして拡張できるかを少し考えてみたい。

© Copyright 2001-2005 Fawcette Technical Publications

注目のテーマ