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