Запуск службы Windows внутри консольного приложения

 Я почти всегда использую один и тот же фрагмент кода при работе со службой Windows. Основная проблема со службой Windows заключается в том, что ее необходимо установить перед запуском. Хотя это прекрасно работает при развертывании приложения, мы должны иметь возможность отлаживать и запускать службу, не устанавливая ее во время разработки.

Запуск Сервиса как Сервиса

Предположим, у нас есть консольное приложение со службой Windows с именем «Служба». Код для запуска этого сервиса, когда наше приложение установлено, довольно прост.

static void Main(string[] args)
{
    AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

    var service = new Service();

    ServiceBase.Run(new ServiceBase[] { service });

    AppDomain.CurrentDomain.UnhandledException -= CurrentDomain_UnhandledException;
}

Мы можем использовать это, только если наше приложение установлено в качестве службы. Если вы попытаетесь запустить этот код из Visual Studio, вы получите следующую ошибку:

Не удается запустить службу из командной строки или отладчика. Сначала необходимо установить службу Windows (с помощью installutil.exe), а затем запустить ее с помощью ServerExplorer, средства администрирования служб Windows или команды NET START.

Запуск службы как консольного приложения

Сначала нам нужно изменить класс ‘Service’, чтобы иметь возможность вызывать методы OnStart и OnStop , которые защищены по умолчанию.

public void ManualStart(string[] args)
{
    OnStart(args);
}

public void ManualStop()
{
    OnStop();
}

Теперь нам просто нужно изменить наш метод Main, чтобы запустить службу, а затем ждать ввода от пользователя. Я собираюсь использовать директивы компилятора здесь — я хочу, чтобы приложение запускалось как консольное приложение в режиме отладки и запускалось как служба Windows в режиме выпуска . Это означает, что мне нужно развернуть свое приложение в режиме выпуска , но вы, вероятно, должны делать это в любом случае.

static void Main(string[] args)
        {
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

            var service = new Service();
#if DEBUG
            service.ManualStart(args);

            Console.WriteLine("Service started, press any key to kill");
            Console.ReadKey();

            service.ManualStop();
#else
            ServiceBase.Run(new ServiceBase[] { service });
#endif

            AppDomain.CurrentDomain.UnhandledException -= CurrentDomain_UnhandledException;
        }

Теперь наше приложение запустится как консольное приложение в режиме отладки и как служба Windows в режиме выпуска .

Убей только сервис по Ctrl-C

Я использовал этот код довольно часто и быстро понял, что остановка службы при нажатии клавиши довольно раздражает — вы склонны делать это случайно пару раз в день. Чтобы обойти это, я просто изменил код, чтобы остановить службу только при нажатии Ctrl-C.

Console.WriteLine("Service started, press Ctrl-C to kill");
Console.TreatControlCAsInput = true;
while (true)
{
    var keyInfo = Console.ReadKey(true);
    if (keyInfo.Key == ConsoleKey.C && keyInfo.Modifiers == ConsoleModifiers.Control)
    {
        break;
    }
}

Удачного кодирования.

Интернет по оптике в Миассе AirNet

Author: admin