Современная концепция практически любой операционной системы, на текущий момент, подразумевает наличие системы инициализации или же Windows Services. Но зачем она вообще нужна? И какие задачи решает?
Для корректной работы системы необходимы сервисы, которые будут обеспечивать работу сети, файловой системы, будут взаимодействовать с инфраструктурой. Их должен кто-то запускать, знать в каком порядке это делать, а так же когда и при каких условиях. Такую роль на себя вполне мог взять модуль ядра или даже само ядро, однако, потребность в постоянном изменении состава служб и их конфигурации заставило отказаться от такой идеи и перенести ПО в пользовательское пространство.
Windows Service стал приложением services.exe, которое позволило реализовать функциональность оркестрации служб. Ядро после полной инициализации себя и своих компонентов запускает ряд приложений, в том числе services.exe, который считывает в заранее сформированный конфиг и по определенным условиям и по порядку запускает системные и пользовательские службы.
Он, буквально, является родительским процессом для многих запущенных на ОС. Поэтому управлять ими так же можно через единую панель оснастки для служб.
Как просмотреть службы в Windows?
Самый простой способ это использовать PowerShell c его заранее заготовленными командлетами, список всех можно просмотреть вызвав команду:
Список командлетов достаточный для того, чтобы полноценно управлять службами в Windows. Рассмотрим их применение на конкретных кейсах, к примеру, нам необходимо быстро найти список всех служб:
Или тех, которые на текущей момент находятся в состоянии “остановлены”. Для этого мы можем поиграть с параметром фильтра Where-Object, который позволит найти по свойству объекта сервиса все подходящие службы:
Так же мы можем просмотреть все запущенные процессы альтернативной командой, где измени “Stopped” на “Running“:
Для быстрого поиска можно так же задействовать другие поля объекта, к примеру, если вы знаете примерное название вашей службы.
Как остановить, запустить службы Windows?
Используем командлет из представленного списка ранее, который позволит выполнить действие остановки над объектом Services:
Такая ошибка говорит, о том что не хватило прав обычного пользователя на выполнение команды, поэтому запустите PowerShell заново от лица Администратора Win+X → Terminal(Administrator)/Powershell(Administrator):
Аналогично, можно приостановить, либо же стартовать какой либо из сервисов:
Действию приостановке/продолжению соответствуют, команды:
Но если нам необходимо создать свою службу Windows для выполнения задач с прослушиванием сокетов, запускаемую от лица Администратора?
Как создать свою службу Windows?
Services.exe, которое является системой инициализации использует юниты или краткий профиль службы/приложения для автоматизации их запуска. В отличие от Linux-подобных систем, где общение со службой происходит на уровне управления дочерними процессами с обработкой сигналов, то в Windows Services требуется внутренняя обработка API-запросов.
Если у вас ПО заранее подготовлено с использованием обработчиков API Windows, то можно использовать команду:
Name = “My_Service”
BinaryPathName = ‘C:\Windows\System32\svchost.exe’
DisplayName = “New Service”
StartupType = “Manual”
Description = “This is a test service.”
}
New-Service @params
Но обычный скрипт или ПО, без функций обработчиков внутри, запустить просто не получится. Процесс services.exe не получит ответ от службы:
Для таких случаев был разработан менеджер служб NSSM или же Non-Sucking Service Manager, который становится бинарным прокси между вами и Services.exe.
Работает это так, в Windows services регистрируется запись Binary = nssm “App1“ “Arg1“. А значит, что API запрос будет передан на управление утилите nssm, а она в свою очередь конвертирует его в обычный сигнал и начнет управлять дочерним процессом:
Рассмотрим в экспресс формате, как можно таким способом создать сервис. Во-первых, установите nssm с официального сайта разработчика или используйте пакетный менеджер через терминал:
После откройте терминал и пропишите команду:
$serviceName = ‘My_servv’
$powershell = (Get-Command powershell).Source
$scriptPath = ‘D:\service.ps1’
$arguments = ‘-ExecutionPolicy Bypass -NoProfile -File “{0}”’ -f $scriptPath
& $nssm install $serviceName $powershell $arguments
& $nssm status $serviceName
Start-Service $serviceName
А после чего необходимо прописать команду, для проверки запущенной службы:
Как видим результат запуска показал, что служба находится в состоянии Running и способна обрабатывать пользовательские запросы.
В результате не сложных манипуляций мы получили работающую службу, которая общается через посредника nssm, способного управлять юнитами и обрабатывать запросы по API. Подобный механизм системы инициализации позволяет автоматизированно запустить не только службы, для которых изначально предназначен, но и иные ПО для обеспечения работоспособности ОС.