Службы в Windows — особые процессы, выполняемые в фоновом режиме, в том числе от учетной записи «СИСТЕМА», которые могут быть запущены в том числе до входа в систему. При желании вы можете создать свою собственную службу, которая будет работать таким же образом.
В этой инструкции подробно о том, как создать службу в Windows 11 или Windows 10 средствами системы, ограничениях методов и одном дополнительном способе заставить работать ваш процесс в качестве службы.
Создание службы в командной строке
Первый способ — использование команды командной строки для создания своей службы, шаги будут следующими:
- Запустите командную строку от имени Администратора (способы запуска командной строки от Администратора).
- Используйте команду, заменив текстовые описания и пути на свои:
sc create Имя_службы binPath="C:\service-file.exe" DisplayName= "Описание_службы" type=own start=auto
- После нажатия Enter вы получите сообщение: CreateService: успех, что означает, что служба была успешно создана.
В указанной команде используются следующие параметры:
- binPath — путь к исполняемому файлу службы.
- DisplayName — отображаемое в списке служб имя службы.
- start — тип запуска, возможные значения: boot, auto, demand (значение по умолчанию), disabled, delayed-auto
- type — тип службы, по умолчанию own, возможны другие значения: share (делит исполняемый файл с другими службами), kernel (драйвер), filesys (драйвер файловой системы), interact (интерактивная служба с возможность взаимодействия с пользователем, поддержка этого типа служб прекращается).
После создания службы вы сможете увидеть её в списке служб (Win+R — services.msc), а автоматический запуск произойдет при следующей перезагрузке системы.
Создание службы в Windows PowerShell
Создать службу можно и в PowerShell, запущенном от имени администратора (или в Терминале Windows). Базовый вариант команды с параметрами по умолчанию:
New-Service -Name "Имя_Службы" -BinaryPathName '"C:\путь_к_файлу параметры_запуска"'
Расширенный вариант с указанием описания и типа запуска:
New-Service -Name MyService -BinaryPathName '"C:\путь_к_файлу параметры_запуска"' -DisplayName "Имя_службы" -Description "Описание службы" -StartupType "Automatic"
В случае, если выполняется запуск исполняемого файла без параметров, а путь не содержит пробелов, использование кавычек не обязательно, например:
-BinaryPathName C:\remontka.exe
При создании служб в PowerShell доступны и ряд дополнительных параметров, описанных в официальной справке на сайте Майкрософт.
Удаление созданной службы
Удалить созданную службы вы можете также в командной строке, запущенной от имени Администратора с помощью команды:
sc delete Имя_службы
Или в Windows PowerShell:
Remove-Service -Name MyService
После выполнения указанных команд созданная вами служба будет удалена из Windows.
Созданная служба не работает, варианты решения
Из описания можно предположить, что любой файл .exe может быть службой, однако, при попытке добавить свои фоновые утилиты и заставить их работать в виде службы рядовые пользователи обычно сталкиваются с ситуацией, когда процесс запускается, а затем закрывается сам. А при запуске службы вручную через некоторое время сообщает, что служба не ответила на запрос своевременно или о других ошибках.
Причина в том, что исполняемые файлы служб — не совсем обычные программы, они, помимо прочего, обмениваются данными с системой. Если ваш EXE не отвечает на соответствующие запросы системы, Windows «делает вывод» о том, что со службой что-то не так.
Как быть, если вы всё-таки настойчиво хотите использовать свой прикладной исполняемый файл в качестве службы?
- Использовать планировщик заданий и запуск от соответствующего пользователя — это не будет в полной мере службой, но почти то, что нужно.
- Ранее существовала программа RunAsSvc, позволяющая запускать любые процессы в качестве службы, но для современных ОC он не применима, а разработка была прекращена.
- Использовать инструменты INSTSRV.EXE и SRVANY.EXE из Windows Server 2003 Resource Kit Tools при создании службы Windows.
Создание пользовательской службы с помощью INSTSRV.EXE и SRVANY.EXE
Последний вариант из приведённого выше списка рассмотрим подробнее. Шаги будут следующими:
- Загрузите (вероятнее всего, придется найти в Интернете на сторонних сайтах) Windows Server 2003 Resource Kit полностью или только файлы INSTSRV.EXE и SRVANY.EXE, располагаем их у себя на диске, в моем примере путь — C:\Windows
- В командной строке от имени администратора используйте команду (пути меняем на свои):
C:\Windows\instsrv.exe Имя_службы C:\Windows\srvany.exe
- Если вы получили сообщение о том, что The service was successfully added, всё прошло успешно. Теперь требуется запустить редактор реестра (Win+R — regedit).
- В редакторе реестра перейдите по пути
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\
и найдите раздел с вашим именем службы. Нажимаем по нему правой кнопкой мыши и выбираем пункт «Создать» — «Раздел», задаем имя «Parameters» для раздела.
- Выберите созданный раздел, нажмите правой кнопкой мыши в правой панели редактора реестра и создайте новый строковый параметр с именем Application
- Дважды нажмите по параметру и в поле «Значение» укажите путь к вашему файлу exe для запуска службы.
Закройте редактор реестра — служба создана, её можно запустить из services.msc или она будет автоматически запущена после перезагрузки компьютера.
Учитывайте, что во всех приведенных примерах служба по умолчанию запускается с учетной записью «СИСТЕМА». В некоторых случаях это может приводить к неправильной работе. В этом случае может иметь смысл зайти в свойства службы в services.msc и изменить параметры на вкладке «Вход в систему».
Время на прочтение3 мин
Количество просмотров143K
Многие из нас сталкиваются с такой задачей, когда нужно запускать своё приложение при запуске компьютера. Конечно можно поместить ярлык в автозагрузку, но как-то это неправильно. Да к тому же если комп перегрузился, а пользователь не залогинелся, то и ваше приложение тоже не запустится.
Самым верным решением в данной ситуации является написание Windows сервиса.
Пример создания сервиса в Studio 2010, .Net C# под катом
Шаг 1. Создание проекта.
Создайте новый проект, выбрав шаблон Windows Service
Переименуйте класс сервиса как вам нужно.
Получили такой вод код:
namespace ExampleSrv
{
public partial class MyService : ServiceBase
{
public MyService()
{
InitializeComponent();
}protected override void OnStart(string[] args)
{
}protected override void OnStop()
{
}
}
}* This source code was highlighted with Source Code Highlighter.
Это и есть, собственно, сам сервис.
Используйте OnStart и OnStop события для реализации своей поставленной задачи.
Шаг 2. Добавление установщика.
Чтобы ваш сервис заставить работать, его нужно установить.
Чтобы его установить, он должен иметь установщик.
Клик правой кнопкой… Add installer
Теперь у нас есть serviceProcessInstaller и serviceInstaller
В первом можете поставить значение Account в LocalSystem.
Во втором укажите имя сервиса, описание и не забудьте поставить StartType — Automatic.
Установщик готов.
Шаг 3. Логирование.
Для того чтобы вы смогли узнать что делал ваш сервис, когда он стартовал, завершался или что-нибудь еще, вы можете использовать системное логирование.
Делается это очень легко.
Перетаскиваете из Toolbox в свой сервис EventLog.
Примерно так делается логирование:
public partial class MyService : ServiceBase
{
public MyService()
{
InitializeComponent();
}protected override void OnStart(string[] args)
{
AddLog("start");
}protected override void OnStop()
{
AddLog("stop");
}public void AddLog(string log)
{
try
{
if (!EventLog.SourceExists("MyExampleService"))
{
EventLog.CreateEventSource("MyExampleService", "MyExampleService");
}
eventLog1.Source = "MyExampleService";
eventLog1.WriteEntry(log);
}
catch{}
}
}* This source code was highlighted with Source Code Highlighter.
Шаг 4. Установка.
Чтобы установить сервис, нужно вызвать утилиту установки и передать параметром путь к своему сервису.
Для этого я создал install.bat такого вида:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\installutil.exe D:\...\ExampleSrv\bin\Debug\ExampleSrv.exe
pause
Если вы выбрали в serviceProcessInstaller значением поля Account — User, то при установке вы должны будете ввести логин и пароль учетной записи, под которой будет запускаться сервис. Внимание! Писать домен перед именем пользователя обязательно!
Запускаем батник обязательно с правами администратора и наблюдаем в конце:
The Commit phase completed successfully.
The transacted install has completed.
Это значит что сервис установлен.
Проверяем:
Установился.
Пару раз делаем запуск и остановку. Смотрим логи:
Видим когда сервис запускался и останавливался.
Наш сервис готов.
Материал частично взят от сюда:
msdn.microsoft.com/en-us/library/zt39148a(VS.80).aspx
Все способы:
- Способ 1: Консольная утилита sc.exe
- Способ 2: Консоль «PowerShell»
- Способ 3: Сторонние программы
- Вопросы и ответы: 0
Способ 1: Консольная утилита sc.exe
Назначить любой процесс системной службой в Windows 10 можно с помощью маленькой консольной утилиты sc.exe, входящей в состав операционной системы. Для обращения к ней можно использовать как классическую «Командную строку», так и консоль «PowerShell».
- Запустите от имени администратора «Командную строку» или «PowerShell». Первую можно открыть из поиска Windows, вторую – из контекстного меню кнопки «Пуск».
- Сформируйте команду следующего вида:
sc create MyService binPath="C:\MyService.exe" DisplayName= "MyNewService" type=own start=auto
. В качестве параметра MyService binPath укажите свой путь к исполняемому файлу создаваемой службы, а в качестве параметра DisplayName — имя службы, которое станет отображаться в оснастке управления службами. - Вставьте сформированную команду в консоль и нажмите клавишу ввода.
Готово, осталось только проверить корректность создания службы в системной оснастке «Службы», запустить которую можно командой services.msc
в диалоговом окошке, вызванном клавишами Win + R.
Способ 2: Консоль «PowerShell»
Необходимыми средствами создания служб в Windows 10 располагает другой штатный инструмент – консоль «PowerShell».
- Запустите «PowerShell» от имени администратора.
- Сформируйте команду вида
New-Service -Name MyService -BinaryPathName C:\MyService.exe -DisplayName "Отображаемое имя службы" -Description "Описание службы"
. Имя и описание службы могут быть произвольными. - Вставьте команду в консоль и нажмите клавишу ввода.
Проверьте корректность работы в оснастке управления службами, там же ее можно настроить.
Способ 3: Сторонние программы
Также для создания собственных служб в Windows 10 можно использовать специализированные сторонние утилиты, например Non-Sucking Service Manager. Утилита работает через «Командную строку», но у нее также имеется и графический интерфейс.
Скачать Non-Sucking Service Manager с официального сайта
- Скачайте архив с утилитой с сайта разработчика и распакуйте в удобное расположение — к примеру, поместите исполняемый файл nssm.exe в корень системного диска.
- Запустите «Командную строку» от имени администратора.
- Выполните команду
C:\nssm.exe install MyService
, где MyService – название создаваемой службы. - В открывшемся окошке инсталлятора в поле «Patch» укажите полный путь к исполняемому файлу службы и нажмите кнопку «Install service».
- Служба будет установлена, подтверждением чему станет появление окошка с уведомлением «Service *Name* installed successfully!». Нажмите в нем «OK» и закройте «Командную строку».
Остальные поля в окошке инсталлятора службы заполнять не обязательно, кроме тех случаев, когда в качестве службы устанавливается командный файл, например CMD, BAT или PS1. В этом случае в поле «Patch» указывается путь к приложению-обработчику, а в поле «Arguments» – путь к файлу скрипта.
Наша группа в TelegramПолезные советы и помощь
Иногда может потребоваться взять исполняемый файл и зарегистрировать его в качестве службы Windows. Для этого есть несколько способов, я обычно пользуюсь двумя из них.
Sc.exe
Для создания и службы из командной строки можно использовать программу SC (Sc.exe). SC представляет из себя утилиту командной строки, которая реализует вызовы ко всем функциям интерфейса прикладного программирования (API) управления службами Windows. С ее помощью можно производить любые действия со службами — просматривать состояние, управлять (запускать, останавливать и т.п.), изменять параметры, а также создавать новые службы.
При создании службы с помощью SC нет необходимости вручную создавать записи в реестре и затем перезагружать компьютер, чтобы обеспечить обновление базы данных диспетчером служб. Также SC позволяет указать имя удаленного компьютера, что дает возможность управлять службами как на локальном, так и на удаленном компьютере.
Для создания нового сервиса запускаем команду Sc create. Она создает запись службы в реестре и в базе данных диспетчера служб. Sc create имеет следующий синтаксис:
sc create [ServiceName] [binPath= ] <параметр1= > <параметр2= >
ServiceName — указывает имя, которое будет присвоено разделу службы в реестре. Имейте в виду, что это имя отличается от отображаемого имени службы (имени, которое отображается в оснастке «Services»);
binPath — указывает путь к исполняемому файлу службы.
Для примера создадим службу MyService, укажем отображаемое имя My New Service, зададим тип службы и поставим ее на авто-запуск:
Sc create MyService binPath=C:\MyService\MyService.exe DisplayName=″My New Service″ type=own start=auto
Затем откроем оснастку «Services» и посмотрим результат.
Изменять параметры уже созданной службы можно командой Sc config. Например, мне не понравилось отображаемое имя службы и я хочу его изменить:
Sc config MyService DisplayName=″My Service″
Ну и полностью удалить службу можно вот так:
Sc delete MyService
PowerShell
PowerShell может почти все 🙂 , в том числе и управлять службами Windows. Создать новую службу можно с помощью командлета New-Service. Создадим такой же сервис, как и в предыдущем примере, только добавим к нему описание (Description):
New-Service -Name MyService -BinaryPathName C:\MyService\MyService.exe`
-DisplayName ″My New Service″ -Description ″Very Important Service !!!″
Изменить параметры службы можно командлетом Set-Service:
Set-Service -Name MyService -Description ″Not Very Important Service″ -StartupType Manual
В принципе PowerShell имеет примерно такой же функционал как и Sc.exe, разве что позволяет добавить описание. А вот для удаления служб в PS простого способа нет, придется воспользоваться вот такой конструкцией:
(Get-WmiObject win32_service -Filter ″name=′MyService′″).delete()
Поэтому лично я предпочитаю использовать Sc.exe.
Консольная утилита sc.exe
В составе операционной системы Windows идёт утилита sc, которую можно без проблем вызвать в командной строке sc /?. С её помощью можно изменить любые свойства сервиса. Описание на сайте Microsoft [ссылка]. Примеры:
- Создание службы (sc create):
sc create NewService DisplayName=»New Service» binpath=c:\windows\system32\NewServ.exe type=share start=auto - Изменение службы (sc config):
sc config NewService binpath= «c:\windows\system32\NewServ.exe» - Удаление службы (sc delete):
sc delete newserv
Для работы с sc следует понимать одну вещь, что у службы есть идентификатор (Service Name) и имя службы (Display name), все изменения делаются используя идентификатор, который можно посмотреть в свойствах службы, пример:
Программа Service Manager
Для упрощение создания, изменения и удаления служб я написал небольшую программу под название Service Manager, которая в простом UI режиме даёт возможность делать то, что умеет sc утилита и даже больше.
Требование:
Наличие установленного .NET Framework 4.5
Ссылка для скачивания собранной программы: [LINK1]
Ссылка на исходный код, язык C#: [LINK2]
Для компиляции использовать Visual Studio 2017
Внешний вид окна:
Описание работы
- В списке можно увидеть установленные службы.
- При выделении службы, снизу можно видеть дополнительную информацию о ней.
- Каждый столбец можно сортировать по имени нажимая на него.
- Список служб и значения их полей обновляется каждые 3 секунды.
После выбора службы доступно контекстное меню:
- Start — запуск выбранного сервиса
- Start with arguments — запустить (единожды) службу и передать ей параметры в метод OnStart(string[] args), не путать с аргументами командной строки. (Данной возможности нет в service.msc)
- Stop — попытка остановки сервиса, при этом он может перейти в состояние StopPadding и придётся вручную его убивать в диспетчере задач.
- Terminate — принудительная остановка служб без ожидания её завершения. У запущенной службы находится её PID процесса и он убивается. При этом мы гарантированно останавливаем процесс.
- Create — диалог создания новой службы.
- Edit — диалог редактирования выделенной службы.
- Delete — удаление выделенной службы.
Далее будет демонстрация работу каждого функционала
Запуск сервиса (Start)
Остановка сервиса (Start with parameters)
Остановка сервиса (Stop)
Принудительная остановка сервиса (Terminate)
Создание службы (Create)
Редактирование службы (Edit)
Удаление службы (Delete)
Как это работает?
Работы с сервисами идёт через WinAPI функции реакция на изменение сервиса которыми происходит сразу после вызова, что не скажишь об изменении службы в реестре (для применения потребуется перезагрузка). В качестве UI представления используется WPF с шаблоном MVVM и объекты Prism, а для компиляции Visual Studio 2017. Список WinAPI функций:
/// <summary> /// Windows native methods. /// </summary> internal class NativeMethods { [DllImport("advapi32.dll", EntryPoint = "OpenSCManagerW", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)] public static extern IntPtr OpenSCManager( string machineName, string databaseName, ScmAccessRights dwDesiredAccess); [DllImport("advapi32.dll", SetLastError = true)] public static extern bool QueryServiceStatusEx( SafeHandle hService, int infoLevel, IntPtr lpBuffer, uint cbBufSize, out uint pcbBytesNeeded); [DllImport("kernel32.dll")] public static extern int GetLastError(); [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "QueryServiceConfig2W")] public static extern Boolean QueryServiceConfig2( IntPtr hService, UInt32 dwInfoLevel, IntPtr buffer, UInt32 cbBufSize, out UInt32 pcbBytesNeeded); [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool ChangeServiceConfig2( IntPtr hService, int dwInfoLevel, [MarshalAs(UnmanagedType.Struct)] ref ServiceDescriptionStruct lpInfo); [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CloseServiceHandle(IntPtr hScObject); [DllImport("advapi32.dll")] public static extern int ControlService( IntPtr hService, ServiceControl dwControl, ServiceStatus lpServiceStatus); // https://docs.microsoft.com/en-us/windows/desktop/api/winsvc/nf-winsvc-createservicea [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern IntPtr CreateService( IntPtr hScManager, string lpServiceName, string lpDisplayName, ServiceAccessRights dwDesiredAccess, ServiceType dwServiceType, ServiceBootFlag dwStartType, ServiceError dwErrorControl, string lpBinaryPathName, string lpLoadOrderGroup, IntPtr lpdwTagId, string lpDependencies, string lpServiceStartName, string lpPassword); [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool DeleteService(IntPtr hService); [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern IntPtr OpenService( IntPtr hScManager, string lpServiceName, ServiceAccessRights dwDesiredAccess); [DllImport("advapi32.dll")] public static extern int QueryServiceStatus(IntPtr hService, ServiceStatus lpServiceStatus); [DllImport("advapi32.dll", SetLastError = true)] public static extern int StartService(IntPtr hService, int dwNumServiceArgs, int lpServiceArgVectors); [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] public static extern bool ChangeServiceConfig( IntPtr hService, ServiceType nServiceType, ServiceBootFlag nStartType, ServiceError nErrorControl, string lpBinaryPathName, string lpLoadOrderGroup, int lpdwTagId, string lpDependencies, string lpServiceStartName, string lpPassword, string lpDisplayName); [DllImport("shell32.dll", SetLastError = true)] public static extern IntPtr CommandLineToArgvW( [MarshalAs(UnmanagedType.LPWStr)] string lpCmdLine, out int pNumArgs); [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] public static extern Boolean QueryServiceConfig( IntPtr hService, IntPtr intPtrQueryConfig, int cbBufSize, out int pcbBytesNeeded); }
Пример работы с этими функциями можно найти в исходных кода программы, ссылку для скачивания
https://github.com/devowl/winservicemanager