2009-03-20 4 views
4

서비스 시작 (OnStart) 중에 작업자 스레드가 시작되는 경우가 있습니다. 작업자 스레드는 SQL 데이터베이스에 연결합니다. 데이터베이스를 사용할 수없는 경우 작업자 스레드는 실패의 주 스레드에 신호를 보낼 수 있습니다. 질문은 ~이야; 서비스 제어 관리자가 시작에 실패했음을 알리는 방법Service.OnStart에서 신호 초기화 실패

답변

3

이것은 우리가이 상황을 처리 한 방법입니다. 이 코드는 우리의 주 서비스 클래스에 추가 된 다음 시작 실패를 반환하려는 시점에서 SetServiceFail (1065)을 호출 한 다음 OnStart에서 반환했습니다. 이 경우 1065는 데이터베이스가 존재하지 않는 상태를 반환합니다.

SetServiceFail에서 serviceType을 하드 코딩 했으므로 우리의 모든 서비스가 독립형이므로 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를 사용하는 것입니다 중지,하지만 당신은 늘 오류 또는 시작 실패에 대한 서비스 제어 관리자에있는 멋진 메시지가 표시됩니다.


var controller = new System.ServiceProcess.ServiceController("NameOfYourService"); 
controller.Stop();