Ошибка инициализации сигнализации от Service.OnStart - PullRequest
4 голосов
/ 20 марта 2009

У нас есть случай, когда во время запуска службы (OnStart) запускается рабочий поток. Рабочий поток подключается к базе данных SQL. Если база данных недоступна, рабочий поток может сигнализировать основному потоку об ошибке. Вопрос в том; Как сообщить диспетчеру управления службами, что запуск не удался.

Ответы [ 2 ]

3 голосов
/ 20 марта 2009

Вот как мы справились с этой ситуацией. Этот код был добавлен в наш основной класс обслуживания, а затем в тот момент, когда мы хотели вернуть запуск при сбое, вызвал 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 голосов
/ 20 марта 2009

Один из способов остановить это - использовать ServiceController, но вы не получите никакого необычного сообщения в диспетчере управления службами об ошибке или сбое при запуске.


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