Windowsサービスの制御
Windowsサービスにはいくつかの基本的な特性があります。まず、Windowsサービスは特定ユーザーの下で実行するように設定できます。また、Windowsサービスは親あるいは子サービスを持つことができます。親サービスとは、そのサービスが依存するサービスのことで、子サービスとは、そのサービスに依存するサービスのことです。この関係は、サービスの起動/停止の際に重要な意味を持ちます。サービスを正しく起動させるには、そのサービスの親サービスが起動していることを確認する必要があります。サービスを正しく停止させるには、そのサービスの子サービスが停止していることを確認する必要があります。
サービスの起動
それでは、実際のコードを見てみましょう。VB.Netでサービスを制御するには、サービスプロセスの名前空間をインポートする必要があります。よって、最初の行は次のようになります。
Imports System.ServiceProcess
まず、親サービスとの依存関係を何も確認せずにサービスを起動するコードを考えてみましょう。
Dim objWinServ As New ServiceController objWinServ.ServiceName = sServiceName objWinServ.MachineName = MachineName StartService(objWinServ) Private Sub StartService(ByVal Service As ServiceController) If Service.Status = ServiceControllerStatus.Stopped Then Try Service.Start() Service.WaitForStatus(ServiceControllerStatus.Running, _ System.TimeSpan.FromSeconds(20)) Catch ex As TimeoutException Status = "Could not Start " & Service.DisplayName & _ " - TimeOut expired" Catch e As Exception Status = "Could not Start " & Service.DisplayName & _ " - " & e.Message End Try End If End Sub
このコードはごく単純なもので、次のことを行っています。
objWinServ
という名称の新規サービスコントローラを作成します。- サービス名とマシン名を割り当てます(リモートで呼び出しを行うため)。
objWinServ
オブジェクトをサービス起動ルーチンに提供します。- 起動ルーチンは最初に目的のサービスのステータスをチェックし、サービスが停止しているかを確認します。同じ要領で、一時停止状態や実行中などの確認もできます。
- その後、起動ルーチンはサービスの起動を試みます。この例では、起動の最大待ち時間を20秒に設定しました。サービスが起動しない場合は、タイムアウト例外がスローされます。その他の一般的な例外についての処理も用意してあります。
ここで、コードの確実性をより高めるために次の2点をチェックするようにしたいと思います。
- 事前に起動している必要がある親サービス
- サービスがサーバ上に存在しているか
起動しておく必要がある親サービスを確認するには、以下の再帰プロシージャを使用します。
Private Sub CheckForParentServices _ (ByVal Service As ServiceController) Dim objParentService As ServiceController For Each objParentService In Service.ServicesDependedOn CheckForParentServices(objParentService) Next Call StartService(Service) End Sub
objWinServ
オブジェクトをこのプロシージャに渡せば、後は再帰的に処理が行われます。
サービスが存在するかチェックするには、サービスの有無に応じてブール値を返す、以下の関数を使用します。
Public Function CheckforService(ByVal ServerName As String, _ ByVal ServiceName As String) As Boolean Dim Exist As Boolean = False Dim objWinServ As New ServiceController Dim ServiceStatus As ServiceControllerStatus objWinServ.ServiceName = ServiceName objWinServ.MachineName = ServerName Try ServiceStatus = objWinServ.Status Exist = True Catch ex As Exception Finally objWinServ = Nothing End Try Return Exist End Function