2009-03-20 19 views
4

Service起動(OnStart)中にワーカースレッドが開始されるケースがあります。ワーカースレッドはSQLデータベースに接続します。データベースが使用できない場合、ワーカースレッドは、メインスレッドに失敗の旨を伝えることができます。質問は;起動が失敗したことをService Control Managerに通知する方法。Service.OnStartからのシグナリング初期化エラー

答えて

3

これが私たちがこの状況をどのように処理したかです。このコードはメインのサービスクラスに追加され、起動が失敗した場合はSetServiceFail(1065)が呼び出され、その後OnStartからの戻りが返されました。この場合、1065はデータベースが存在しない状態を返します。

私はSetServiceFailでserviceTypeをハードコードしていることにも気付くでしょう。私たちのケースでは私たちのサービスはすべてスタンドアローンであるため、私はそれを単純なものにしました。

private void SetServiceFail (int ErrorCode) 
{ 
    SERVICE_STATUS _ServiceStatus = new SERVICE_STATUS(); 
    _ServiceStatus.currentState = (int) State.SERVICE_STOPPED; 
    _ServiceStatus.serviceType = 16; //SERVICE_WIN32_OWN_PROCESS 
    _ServiceStatus.waitHint = 0; 
    _ServiceStatus.win32ExitCode = ErrorCode; 
    _ServiceStatus.serviceSpecificExitCode = 0; 
    _ServiceStatus.checkPoint = 0; 
    _ServiceStatus.controlsAccepted = 0 | 
      (this.CanStop ? (int) ControlsAccepted.ACCEPT_STOP : 0) | 
      (this.CanShutdown ? (int) ControlsAccepted.ACCEPT_SHUTDOWN : 0) | 
      (this.CanPauseAndContinue ? (int) ControlsAccepted.ACCEPT_PAUSE_CONTINUE : 0) | 
      (this.CanHandleSessionChangeEvent ? (int) ControlsAccepted.ACCEPT_SESSION_CHANGE : 0) | 
      (this.CanHandlePowerEvent ? (int) ControlsAccepted.ACCEPT_POWER_EVENT : 0); 
    SetServiceStatus (this.ServiceHandle, ref _ServiceStatus); 
} 

public enum State 
{ 
    SERVICE_STOPPED = 1, 
    SERVICE_START_PENDING = 2, 
    SERVICE_STOP_PENDING = 3, 
    SERVICE_RUNNING = 4, 
    SERVICE_CONTINUE_PENDING = 5, 
    SERVICE_PAUSE_PENDING = 6, 
    SERVICE_PAUSED = 7 
} 

public enum ControlsAccepted 
{ 
    ACCEPT_STOP = 1, 
    ACCEPT_PAUSE_CONTINUE = 2, 
    ACCEPT_SHUTDOWN = 4, 
    ACCEPT_POWER_EVENT = 64, 
    ACCEPT_SESSION_CHANGE = 128 
} 

[StructLayout (LayoutKind.Sequential)] 
private struct SERVICE_STATUS 
{ 
    public int serviceType; 
    public int currentState; 
    public int controlsAccepted; 
    public int win32ExitCode; 
    public int serviceSpecificExitCode; 
    public int checkPoint; 
    public int waitHint; 
} 

[DllImport ("advapi32.dll")] 
private static extern bool SetServiceStatus (IntPtr hServiceStatus, ref SERVICE_STATUS lpServiceStatus); 
0

ServiceControllerを使用することを止める1つの方法は、サービスコントロールマネージャーでエラーまたは開始の失敗についてのメッセージを得ることがありません。


var controller = new System.ServiceProcess.ServiceController("NameOfYourService"); 
controller.Stop(); 
関連する問題