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
