Пилим свою службу Windows – руководство для «не настоящих программистов»
Однажды вы задумаетесь, как превратить скрипт или приложение в Windows-службу. Скорее всего, задача окажется не такой уж тривиальной – приложению как минимум потребуется специальный интерфейс для получения команд от системы. А раз есть требования и ограничения, то есть и скрипты, и милые сердцу костылики для преодоления.
Статья будет полезна тем, кто, как и я — «программист не настоящий».
Зачем нужна служба, если есть назначенные задания
В отличие от назначенных заданий служба работает постоянно, запускается при старте ПК и может управляться средствами Windows. А еще регулярно запускаемому скрипту могут понадобиться данные с предыдущего запуска, и может быть полезно получение данных из внешних источников — например, в случае TCP или Web сервера.
Лично мне за последние пять лет приходилось создавать службу три с половиной раза:
- Потребовалось создать сервис на fail2ban для Windows 2003., который работал с логами FileZilla и Apache, а при подозрении на брутфорс блокировал IP штатными средствами Windows — ipsec.
- Аналог телнет-сервера для домашних версий Windows. Понадобилось выполнять команды на удаленных рабочих станциях, которые были под управлением Windows 7 Home. По сути, вторая попытка поиграть в службы.
- Музыкальный проигрыватель для торгового зала под Windows. Задачу по ТЗ можно было решить при помощи mpd и пачки скриптов, но я решил — если уж делать скрипты, то почему бы и не «сваять» проигрыватель самому. За основу взял библиотеку BASS.dll.
- Когда выбирали веб-сервер с поддержкой загрузки файлов под Windows, одним из вариантов был HFS. Сам по себе работать он не может, поэтому пришлось «запихивать» его в службу. В результате решение не понравилось, и просто установили «тему» Apaxy на web-сервере Apache.
Для создания службы можно использовать взрослые языки программирования вроде C. Но если вы не хотите связываться с Visual Studio, то возьмите готовые утилиты. Существуют платные решения вроде FireDaemon Pro или AlwaysUp, но мы традиционно сосредоточимся на бесплатных.
Способ первый. От Microsoft
Этот уже немолодой механизм состоит из двух компонентов: утилиты instsrv.exe для установки сервиса и srvany.exe — процесса для запуска любых исполняемых файлов. Предположим, что мы создали веб-сервер на PowerShell при помощи модуля Polaris. Скрипт будет предельно прост:

Работа так называемого «сервера».
Теперь попробуем превратить скрипт в службу. Для этого скачаем Windows Resource Kit Tools, где будут наши утилиты. Начнем с того, что установим пустой сервис командой:
Где WebServ — имя нашего нового сервиса. При необходимости через оснастку services.msc можно задать пользователя, под которым будет запускаться служба, и разрешить взаимодействие с рабочим столом.
Теперь пропишем путь к нашему скрипту при помощи магии реестра. Параметры службы есть в разделе реестра HKLM\SYSTEM\CurrentControlSet\Services\WebServ. В нем нам нужно добавить новый раздел Parameters и создать там строковый параметр Application, указав в нем путь к исполняемому файлу. В случае скрипта PowerShell он будет выглядеть так:

Настроенная служба.
Можно запустить и радоваться.

Работающая служба.
Однако у этого способа есть недостатки:
- Утилиты старые, разработаны до изобретения PowerShell, UAC и прочих вещей.
- Srvany не контролирует работу приложения. Даже если оно выпадет в ошибку, служба продолжит свое дело как ни в чем не бывало.
- Придется донастраивать и копаться в реестре. Вы же помните, что копаться в реестре небезопасно?
Поэтому перейдем к методу, частично лишенному этих проблем.
Способ второй, почти взрослый
Существует утилита под названием NSSM — Non-Sucking Service Manager, что можно перевести как не-плохой менеджер служб. В отличие от предыдущей, она поддерживается разработчиком, и исходный код опубликован на сайте. Помимо обычного способа, доступна и установка через пакетный менеджер Chocolately.
Создать сервис можно из обычной командной строки, вооружившись документацией на сайте разработчика. Но мы воспользуемся PowerShell. Потому что можем, разумеется.

Установка через PowerShell.
Для разнообразия проверим работу службы не браузером, а тоже через PowerShell командой Invoke-RestMethod.

И вправду работает.
В отличие от srvany, этот метод позволяет перезапускать приложение на старте, перенаправлять stdin и stdout и многое другое. В частности, если не хочется писать команды в командную строку, то достаточно запустить GUI и ввести необходимые параметры через удобный интерфейс.
GUI запускается командой:

Настроить можно даже приоритет и использование ядер процессора.
Действительно, возможностей куда больше, чем у srvany и ряда других аналогов. Из минусов бросается в глаза недостаточный контроль над всем процессом.
Налицо нехватка «жести». Поэтому я перейду к самому хардкорному методу из всех опробованных.
Способ третий. AutoIT
Поскольку я давний любитель этого скриптового языка, то не смог пройти мимо библиотеки под названием _Services_UDF v4. Она снабжена богатой документацией и примерами, поэтому под спойлером сразу приведу полный текст получившегося скрипта.
Итак, попробуем «завернуть» в нее наш веб-сервис:
Разберу подробнее момент запуска приложения. Он начинается после операции $bServiceRunning = True и превращается в, казалось бы, бесконечный цикл. На самом деле этот процесс прервется, как только служба получит сигнал о завершении — будь то выход из системы или остановка вручную.
Поскольку программа для скрипта является внешней (powershell.exe), то после выхода из цикла нам нужно закончить ее работу с помощью ProcessClose.
Для этого скрипт необходимо скомпилировать в .exe, а затем установить службу, запустив exe с ключом -i.

Оно работает!
Разумеется, этот способ не самый удобный, и все дополнительные возможности придется реализовывать самостоятельно, будь то повторный запуск приложения при сбое или ротация логов. Но зато он дает полный контроль над происходящим. Да и сделать в итоге можно куда больше — от уведомления в Telegram о сбое службы до IPC-взаимодействия с другими программами. И вдобавок — на скриптовом языке, без установки и изучения Visual Studio.
Расскажите, а вам приходилось превращать скрипты и приложения в службы?
Как управлять службами в Windows
Что такое службы
Службы — это вид программ, которые работают в фоне и не требуют действий пользователя.
Службы могут как относиться к операционной системе Windows, так и быть сторонними приложениями. Примеры служб, которые может установить сам пользователь: веб-сервер, удалённый рабочий стол VNC, SSH служба, служба СУБД MySQL.
Управлять службами можно:
- в графическом интерфейсе
- командной строке
- в PowerShell
Настройка служб в графическом интерфейсе
Чтобы открыть менеджер служб, введите в поиск «Службы» и нажмите Enter:

Ещё один способ открыть это окно, нажать Win+r и ввести:

Здесь, в столбце «Имя», вы увидите список служб, работающих в вашей системе, вместе с их Описанием. Вы также сможете увидеть их Статус — независимо от того, запущены они или остановлены, а также Типы запуска и Вход от имени.
Типы запуска служб Windows
Windows 10 предлагает четыре типа запуска:
- Автоматически
- Автоматически (отложенный запуск)
- Вручную
- Отключена
Запуск, остановка, отключение служб Windows
Чтобы запустить, остановить, приостановить, возобновить или перезапустить любую службу Windows, выберите службу и щёлкните её правой кнопкой мыши. Вам будут предложены эти варианты.

Если вы хотите управлять дополнительными опциями, дважды щёлкните Сервис, чтобы открыть окно его свойств.

Здесь, в раскрывающемся меню Тип запуска, вы сможете выбрать тип запуска для Сервиса.
В разделе «Состояние службы» вы увидите кнопки «Запустить», «Остановить», «Приостановить», «Продолжить».
В окне «Свойства» вы также увидите другие вкладки, такие как «Вход в систему», «Восстановление» и «Зависимости», которые предлагают дополнительные параметры и информацию.
После внесения изменений вам нужно будет нажать «Применить».
Управление службами с помощью командной строки
Вы также можете использовать командную строку для запуска, остановки, приостановки, возобновления обслуживания. Чтобы использовать консоль, откройте командную строку или PowerShell с правами администратора и выполните одну из следующих команд.

Чтобы запустить службу:
Например, для запуска службы mysql:
Чтобы остановить службу:
Например, для остановки службы mysql:
Чтобы приостановить службу (не все службы возможно поставить на паузу!):
Чтобы возобновить службу:
Для отключения автозапуска службы:
Например, для отключения последующих запусков службы mysql:
Для включения автозапуска службы:
Например, для включения автозапуска службы mysql:
Перечисление состояний активных служб и драйверов
Перечисление только служб Win32
Для просмотра состояния определённой службы:
Например, чтобы увидеть состояние службы Apache2.4:

Управление службами Windows с помощью PowerShell
PowerShell — это среда автоматизации задач и управления конфигурацией от Microsoft. В этом разделе мы познакомим вас с тем, как управлять службами Windows через PowerShell, поскольку это намного быстрее и эффективнее, чем другие методы.
Как вы, возможно, знаете, одной из наиболее важных частей каждой операционной системы является служба, которая проходит через неё, и в целом можно сказать, что каждая часть операционной системы, которая запускается, имеет определённую службу, которой можно управлять и контролировать.
Вот подробное руководство по использованию PowerShell для управления службами Windows.
Запустите терминал PowerShell с правами администратора. Для этого нажмите Win+x и выберите Windows PowerShell (администратор):

Сначала вы должны получить список доступных служб, используя следующую команду:
Это образец вывода, который вы получите.

В выводе по умолчанию вы увидите 3 основных раздела: Status (Статус), Name (Имя) и DisplayName (Отображаемое имя). Теперь, если вы хотите найти и перечислить конкретный сервис, вы можете отфильтровать любой из параметров.
Показать все службы, названия которых начинаются с wi:

Показать все службы, отображаемые имена которых начинаются с win:

Примечание: если вы хотите получить доступ к другому компьютеру через сеть, вы можете просмотреть список служб для этой системы с помощью этой команды:
Важной частью управления услугами является управление зависимыми службами.
Чтобы получить доступ к списку DependentServices для конкретной службы, мы можем использовать следующую команду:
Вы также можете использовать параметр RequiredServices, чтобы получить список предварительных условий обслуживания.
Таким образом, с помощью приведённых выше команд мы можем найти название службы, которая вам нужна, увидеть статус и связанные службы или их предварительные условия. Теперь рассмотрим команды управления службами.
Для остановки службы с помощью PowerShell вы можете использовать следующую команду:
Последующие примеры будут показываться на службе Apache2.4. То есть в следующих командах замените «Apache2.4» на имя интересующей вас службы.
Для запуска службы в PowerShell вы можете использовать эту команду:
Одной из наиболее часто используемых команд для работы со службами является команда перезапуска службы. Структура команды перезапуска службы такова:
И наконец, следующая команда используется для временного приостановления службы.
Для изменения режима запуска службы используйте команду вида:
В качестве ТИП_ЗАПУСКА могут быть:
- Automatic — служба будет запущена или была запущена операционной системой при запуске системы. Если автоматически запускаемая служба зависит от запускаемой вручную службы, запускаемая вручную служба также запускается автоматически при запуске системы.
- AutomaticDelayedStart — запускается вскоре после загрузки системы.
- Disabled — служба отключена и не может быть запущена пользователем или приложением.
- InvalidValue — не имеет никакого эффекта. Командлет не возвращает ошибку, но StartupType службы не изменяется.
- Manual — служба запускается только вручную, пользователем, с помощью диспетчера управления службами или приложением.
Это наиболее часто используемые команды для управления службами в PowerShell. Для получения дополнительной информации о командах PowerShell и о том, как они работают, используйте команду Get-Help.

