Практическое руководство. Установка и удаление служб Windows
Эта документация не относится к последней версии службы Windows. Последние сведения о службах Windows, использующих BackgroundService и шаблон службы рабочих ролей, см. в следующих разделах:
- Службы рабочей роли в .NET
- Создание службы Windows с использованием BackgroundService
Если вы разрабатываете службу Windows, используя .NET Framework, можно быстро установить приложение службы с помощью служебной программы командной строки InstallUtil.exe или PowerShell. Если вы являетесь разработчиком и хотите создать службу Windows, которую пользователи могут устанавливать и удалять, можно использовать бесплатный набор инструментов WiX Toolset или коммерческие средства, такие как Advanced Installer, InstallShield и другие. См. сведения о создании пакета установщика (классическое приложение Windows).
Если вы хотите удалить службу на своем компьютере, не выполняйте процедуру, описанную в этой статье. Вместо этого определите, какая программа (или программный пакет) установила эту службу, а затем выберите Приложения в параметрах, чтобы удалить эту программу. Многие службы являются составной частью ОС Windows. Если их удалить, это может привести к нестабильной работе системы.
Чтобы использовать процедуру, описанную в этой статье, сначала необходимо добавить установщик службы в свою службу Windows. Дополнительные сведения см. в разделе Пошаговое руководство: создание диспетчера служб Windows.
Проекты служб Windows нельзя запускать напрямую из среды разработки Visual Studio путем нажатия клавиши F5 . Перед запуском проекта необходимо установить службу в проекте.
Запустите обозреватель сервера и убедитесь, что служба установлена или удалена.
Установка с помощью программы InstallUtil.exe
- В меню Пуск выберите каталог Visual Studio версия> , а затем выберите Командная строка разработчика для VS версия> . Появится командная строка разработчика для Visual Studio.
- Откройте каталог, где находится скомпилированный исполняемый файл вашего проекта.
- Запустите InstallUtil.exe из командной строки, указав исполняемый файл проекта в качестве параметра:
installutil .exe
- Для 32-разрядной версии .NET Framework 4 или 4.5 и более поздних версий: если каталог установки Windows — C:\Windows, по умолчанию используется путь C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe.
- Для 64-разрядной версии .NET Framework 4 или 4.5 и более поздних версий: по умолчанию используется путь C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe.
Удаление с помощью служебной программы InstallUtil.exe
- В меню Пуск выберите каталог Visual Studio версия> , а затем выберите Командная строка разработчика для VS версия> . Появится командная строка разработчика для Visual Studio.
- Запустите InstallUtil.exe из командной строки, указав выходные данные проекта в качестве параметра:
installutil /u .exe
Установка с помощью PowerShell
- В меню Пуск выберите Каталог Windows PowerShell и Windows PowerShell.
- Откройте каталог, где находится скомпилированный исполняемый файл вашего проекта.
- Запустите командлет New-Service, используя имя службы и выходные данные проекта в качестве аргументов.
New-Service -Name "YourServiceName" -BinaryPathName .exe
Удаление с помощью PowerShell
- В меню Пуск выберите Каталог Windows PowerShell и Windows PowerShell.
- Выполните командлет Remove-Service, указав в качестве аргумента имя службы.
Remove-Service -Name "YourServiceName"
Примечание Чтобы использовать этот командлет, требуется PowerShell 6 или более поздней версии. Дополнительные сведения см. в статье Установка PowerShell в Windows.
sc.exe delete "YourServiceName"
См. также
- Знакомство с приложениями служб Windows
- Практическое руководство. Создание служб Windows
- Практическое руководство. Добавление установщиков в приложение-службу
- Installutil.exe (установщик)
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Как создать свою службу в Windows 11 и Windows 10

Службы в Windows — особые процессы, выполняемые в фоновом режиме, в том числе от учетной записи «СИСТЕМА», которые могут быть запущены в том числе до входа в систему. При желании вы можете создать свою собственную службу, которая будет работать таким же образом.
В этой инструкции подробно о том, как создать службу в Windows 11 или Windows 10 средствами системы, ограничениях методов и одном дополнительном способе заставить работать ваш процесс в качестве службы.
Создание службы в командной строке
Первый способ — использование команды командной строки для создания своей службы, шаги будут следующими:
sc create Имя_службы binPath="C:\service-file.exe" DisplayName= "Описание_службы" type=own start=auto

В указанной команде используются следующие параметры:
- 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
Удаление созданной службы
Удалить созданную службы вы можете также в командной строке, запущенной от имени Администратора с помощью команды:
sc delete Имя_службы

Или в Windows PowerShell:
Remove-Service -Name MyService
После выполнения указанных команд созданная вами служба будет удалена из Windows.
Созданная служба не работает, варианты решения
Причина в том, что исполняемые файлы служб — не совсем обычные программы, они, помимо прочего, обмениваются данными с системой. Если ваш 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

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\

и найдите раздел с вашим именем службы. Нажимаем по нему правой кнопкой мыши и выбираем пункт «Создать» — «Раздел», задаем имя «Parameters» для раздела.
Закройте редактор реестра — служба создана, её можно запустить из services.msc или она будет автоматически запущена после перезагрузки компьютера.
Учитывайте, что во всех приведенных примерах служба по умолчанию запускается с учетной записью «СИСТЕМА». В некоторых случаях это может приводить к неправильной работе. В этом случае может иметь смысл зайти в свойства службы в services.msc и изменить параметры на вкладке «Вход в систему».
А вдруг и это будет интересно:
- Лучшие бесплатные программы для Windows
- Клавиши Alt и Win поменялись местами — как исправить?
- Ошибка 0x80072efd — как исправить?
- AV Block Remover — убираем блокировку антивирусов и сайтов майнером
- Ошибка 0x80070643 при обновлении KB5034441 — как исправить?
- Загрузочная флешка или карта памяти в balenaEtcher
- Windows 11
- Windows 10
- Android
- Загрузочная флешка
- Лечение вирусов
- Восстановление данных
- Установка с флешки
- Настройка роутера
- Всё про Windows
- В контакте
- Одноклассники
-
Юрий 06.02.2023 в 23:10
Учебник. Создание приложения службы Windows
Эта документация не относится к последней версии службы Windows. Последние сведения о службах Windows, использующих BackgroundService и шаблон службы рабочих ролей, см. в следующих разделах:
- Службы рабочей роли в .NET
- Создание службы Windows с использованием BackgroundService
Из этой статьи вы узнаете, как создать в Visual Studio приложение службы Windows, которое записывает сообщения в журнал событий.
Создание службы
Для начала создайте проект и настройте значения, необходимые для правильной работы службы.
- В Visual Studio в меню Файл последовательно выберите пункты Создать>Проект (или нажмите клавиши CTRL + SHIFT + N ), чтобы открыть окно Новый проект.
- Найдите и выберите шаблон проекта Служба Windows (платформа .NET Framework).
Примечание Если шаблон службы Windows не отображается, может потребоваться установить рабочую нагрузку разработка классических приложений .NET с помощью Visual Studio Installer.
Переименование службы
Измените имя службы с Service1 на MyNewService.
- В Обозреватель решений выберите Service1.cs или Service1.vb, а затем в контекстном меню выберите Переименовать. Переименуйте файл в MyNewService.cs или MyNewService.vb, а затем нажмите клавишу ВВОД . Появится всплывающее окно, предлагающее переименовать все ссылки на элемент кода Service1.
- Выберите Да.

- На вкладке Проект выберите в контекстном меню пункт Свойства. В окне Свойства измените значение ServiceName на MyNewService.

- В меню Файл выберите команду Сохранить все.
Добавление компонентов в службу
В этом разделе к службе Windows будет добавлен настраиваемый журнал событий. Компонент EventLog — это пример типа компонента, который можно добавить в службу Windows.
Добавление возможности работы с настраиваемым журналом событий
- В Обозреватель решений в контекстном меню myNewService.cs или MyNewService.vb выберите Просмотреть Designer.
- На панели элементов разверните узел Компоненты, а затем перетащите компонент EventLog на вкладку Service1.cs [Конструктор] или Service1.vb [Конструктор] .
- В Обозреватель решений в контекстном меню myNewService.cs или MyNewService.vb выберите Просмотреть код.
- Определите пользовательский журнал событий. Для C# измените существующий MyNewService() конструктор, как показано в следующем фрагменте кода. Для Visual Basic добавьте New() конструктор, как показано в следующем фрагменте кода.
public MyNewService() < InitializeComponent(); eventLog1 = new System.Diagnostics.EventLog(); if (!System.Diagnostics.EventLog.SourceExists("MySource")) < System.Diagnostics.EventLog.CreateEventSource( "MySource","MyNewLog"); >eventLog1.Source = "MySource"; eventLog1.Log = "MyNewLog"; >
' To access the constructor in Visual Basic, select New from the ' method name drop-down list. Public Sub New() MyBase.New() InitializeComponent() Me.EventLog1 = New System.Diagnostics.EventLog If Not System.Diagnostics.EventLog.SourceExists("MySource") Then System.Diagnostics.EventLog.CreateEventSource("MySource", "MyNewLog") End If EventLog1.Source = "MySource" EventLog1.Log = "MyNewLog" End Sub
using System.Diagnostics;
Imports System.Diagnostics
Определение действий при запуске службы
В редакторе кода для MyNewService.cs или MyNewService.vb найдите OnStart метод . Visual Studio автоматически создал пустое определение метода при создании проекта. Добавьте код, с помощью которой запись сохраняется в журнале событий при запуске службы:
protected override void OnStart(string[] args)
' To access the OnStart in Visual Basic, select OnStart from the ' method name drop-down list. Protected Overrides Sub OnStart(ByVal args() As String) EventLog1.WriteEntry("In OnStart") End Sub
Опрос
Так как приложение службы предполагает длительное время выполнения, оно обычно опрашивает или отслеживает систему. Отслеживание настраивается в методе OnStart. После начала работы службы метод OnStart должен возвращать управление операционной системе, чтобы она не блокировалась.
Для создания простого механизма опроса используйте компонент System.Timers.Timer. Таймер через определенные интервалы времени генерирует событие Elapsed, при возникновении которых служба может выполнять отслеживание. Компонент Timer используется следующим образом:
- Задайте свойства компонента Timer в методе MyNewService.OnStart .
- Запустите таймер, вызвав метод Start.
Настройка механизма опроса
- Добавьте оператор using в файл MyNewService.cs или оператор Imports в файл MyNewService.vb для пространства имен System.Timers.
using System.Timers;
Imports System.Timers
// Set up a timer that triggers every minute. Timer timer = new Timer(); timer.Interval = 60000; // 60 seconds timer.Elapsed += new ElapsedEventHandler(this.OnTimer); timer.Start();
' Set up a timer that triggers every minute. Dim timer As Timer = New Timer() timer.Interval = 60000 ' 60 seconds AddHandler timer.Elapsed, AddressOf Me.OnTimer timer.Start()
private int eventId = 1;
Private eventId As Integer = 1
public void OnTimer(object sender, ElapsedEventArgs args) < // TODO: Insert monitoring activities here. eventLog1.WriteEntry("Monitoring the System", EventLogEntryType.Information, eventId++); >
Private Sub OnTimer(sender As Object, e As Timers.ElapsedEventArgs) ' TODO: Insert monitoring activities here. eventLog1.WriteEntry("Monitoring the System", EventLogEntryType.Information, eventId) eventId = eventId + 1 End Sub
Задачи можно выполнять с помощью фоновых рабочих потоков, а не выполнять всю работу в основном потоке. Для получения дополнительной информации см. System.ComponentModel.BackgroundWorker.
Определение действий при остановке службы
Вставьте в метод OnStop строку кода, с помощью которой запись сохраняется в журнале событий при остановке службы:
protected override void OnStop()
Protected Overrides Sub OnStop() EventLog1.WriteEntry("In OnStop.") End Sub
Определение других действий для службы
Вы можете переопределить методы OnPause, OnContinue и OnShutdown, добавив дополнительные процессы обработки.
В следующем коде показано, как можно переопределить OnContinue метод в MyNewService классе :
protected override void OnContinue()
Protected Overrides Sub OnContinue() EventLog1.WriteEntry("In OnContinue.") End Sub
Установка состояния службы
Службы сообщают о своем состоянии диспетчеру служб, чтобы пользователь мог определить, работает ли служба правильно. По умолчанию служба, которая наследуется от ServiceBase, сообщает ограниченный набор состояний, включая SERVICE_STOPPED, SERVICE_PAUSED и SERVICE_RUNNING. Если служба запускается не сразу, полезно обеспечить сообщение состояния SERVICE_START_PENDING.
Состояния ERVICE_START_PENDING и SERVICE_STOP_PENDING можно реализовать путем добавления кода, вызывающего функцию Windows SetServiceStatus.
Реализация состояния ожидания службы
- Добавьте оператор using в файл MyNewService.cs или оператор Imports в файл MyNewService.vb для пространства имен System.Runtime.InteropServices.
using System.Runtime.InteropServices;
Imports System.Runtime.InteropServices
public enum ServiceState < SERVICE_STOPPED = 0x00000001, SERVICE_START_PENDING = 0x00000002, SERVICE_STOP_PENDING = 0x00000003, SERVICE_RUNNING = 0x00000004, SERVICE_CONTINUE_PENDING = 0x00000005, SERVICE_PAUSE_PENDING = 0x00000006, SERVICE_PAUSED = 0x00000007, >[StructLayout(LayoutKind.Sequential)] public struct ServiceStatus < public int dwServiceType; public ServiceState dwCurrentState; public int dwControlsAccepted; public int dwWin32ExitCode; public int dwServiceSpecificExitCode; public int dwCheckPoint; public int dwWaitHint; >;
Public Enum ServiceState 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 End Enum Public Structure ServiceStatus Public dwServiceType As Long Public dwCurrentState As ServiceState Public dwControlsAccepted As Long Public dwWin32ExitCode As Long Public dwServiceSpecificExitCode As Long Public dwCheckPoint As Long Public dwWaitHint As Long End Structure
Примечание Диспетчер служб использует члены dwWaitHint и dwCheckpoint структуры SERVICE_STATUS, чтобы определить время, в течение которого нужно ожидать запуска или завершения работы службы Windows. Если методы OnStart и OnStop выполняются долго, служба может запросить больше времени, повторно вызвав функцию SetServiceStatus с увеличенным значением dwCheckPoint .
[DllImport("advapi32.dll", SetLastError = true)] private static extern bool SetServiceStatus(System.IntPtr handle, ref ServiceStatus serviceStatus);
Declare Auto Function SetServiceStatus Lib "advapi32.dll" (ByVal handle As IntPtr, ByRef serviceStatus As ServiceStatus) As Boolean
// Update the service state to Start Pending. ServiceStatus serviceStatus = new ServiceStatus(); serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING; serviceStatus.dwWaitHint = 100000; SetServiceStatus(this.ServiceHandle, ref serviceStatus);
' Update the service state to Start Pending. Dim serviceStatus As ServiceStatus = New ServiceStatus() serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING serviceStatus.dwWaitHint = 100000 SetServiceStatus(Me.ServiceHandle, serviceStatus)
// Update the service state to Running. serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING; SetServiceStatus(this.ServiceHandle, ref serviceStatus);
' Update the service state to Running. serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING SetServiceStatus(Me.ServiceHandle, serviceStatus)
// Update the service state to Stop Pending. ServiceStatus serviceStatus = new ServiceStatus(); serviceStatus.dwCurrentState = ServiceState.SERVICE_STOP_PENDING; serviceStatus.dwWaitHint = 100000; SetServiceStatus(this.ServiceHandle, ref serviceStatus); // Update the service state to Stopped. serviceStatus.dwCurrentState = ServiceState.SERVICE_STOPPED; SetServiceStatus(this.ServiceHandle, ref serviceStatus);
' Update the service state to Stop Pending. Dim serviceStatus As ServiceStatus = New ServiceStatus() serviceStatus.dwCurrentState = ServiceState.SERVICE_STOP_PENDING serviceStatus.dwWaitHint = 100000 SetServiceStatus(Me.ServiceHandle, serviceStatus) ' Update the service state to Stopped. serviceStatus.dwCurrentState = ServiceState.SERVICE_STOPPED SetServiceStatus(Me.ServiceHandle, serviceStatus)
Добавление установщиков в службу
Перед тем как запускать службу Windows, ее нужно установить. При этом она регистрируется в диспетчере служб. В проект можно добавить установщики, которые обрабатывают сведения о регистрации.
- В обозревателе решений в контекстном меню для файла MyNewService.cs или MyNewService.vb выберите пункт Показать конструктор.
- В представлении Конструктор щелкните область фона правой кнопкой мыши и выберите в контекстном меню команду Добавить установщик. По умолчанию Visual Studio добавляет в проект класс компонента ProjectInstaller , содержащий два установщика. Они предназначены для установки службы и связанного со службой процесса.
- В представлении Конструктор для ProjectInstaller выберите serviceInstaller1 для проекта Visual C# или ServiceInstaller1 для проекта Visual Basic. Затем в контекстном меню выберите пункт Свойства.
- Убедитесь в том, что в окне Свойства свойство ServiceName имеет значение MyNewService.
- Введите для свойства Description какой нибудь текст, например Пример службы. Этот текст отображается в столбце Описание в окне Службы и помогает пользователю понять, для чего служба нужна.

- Введите текст для свойства DisplayName, например Отображаемое имя MyNewService. Этот текст отображается в столбце Отображаемое имя в окне Службы. Это имя может отличаться от значения свойства ServiceName, которое представляет собой имя, используемое в системе (например, когда вы запускаете службу с помощью команды net start ).
- Выберите для свойства StartType значение Automatic в раскрывающемся списке.
- В итоге окно Свойства должно выглядеть так:

- В представлении Конструктор для ProjectInstaller выберите serviceProcessInstaller1 для проекта Visual C# или ServiceProcessInstaller1 для проекта Visual Basic. Затем в контекстном меню выберите пункт Свойства. Выберите для свойства Account значение LocalSystem в раскрывающемся списке. Это позволит установить и запускать службу от имени локальной системной учетной записи.
Важно! У учетной записи LocalSystem имеется множество разрешений, включая разрешение на запись в журнал событий. Эту учетную запись следует использовать с осторожностью, поскольку это может увеличить риск атак с помощью вредоносных программ. Для других задач следует рассмотреть возможность использования учетной записи LocalService , которая аналогична учетной записи непривилегированного пользователя локального компьютера. Удаленным серверам при этом передаются учетные данные анонимного пользователя. В этом примере произойдет ошибка, если вы попытаетесь использовать учетную запись LocalService , так как для нее требуется разрешение на запись в журнал событий.
Дополнительные сведения об установщиках см. в руководстве по добавлению установщиков в приложение-службу.
Установка параметров запуска (необязательно)
Прежде чем добавлять параметры запуска, решите, является ли это наилучшим способом передачи информации в службу. Хотя параметры запуска просты для использования и синтаксического анализа и пользователи могут легко их переопределять, для пользователей их поиск и применение могут оказаться затрудненными (без документации). Как правило, если вашей службе требуется всего несколько параметров запуска, то следует использовать реестр или файл конфигурации.
Служба Windows может принимать аргументы командной строки или параметры запуска. При добавлении кода в параметры запуска процесса пользователь может запускать службу со своими собственными специальными параметрами из окна свойств службы. Однако эти параметры запуска не сохраняются при следующем запуске службы. Задать постоянные параметры запуска можно в реестре.
Для каждой службы Windows создается запись в разделе реестра HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services. Для хранения информации, к которой может обращаться ваша служба, в разделе службы можно использовать подраздел Parameters. Файлы конфигурации приложения для службы Windows можно использовать так же, как и для программ других типов. Пример кода см. в разделе ConfigurationManager.AppSettings.
Добавление параметров запуска
- Выберите файл Program.cs или MyNewService.Designer.vb, а затем в контекстном меню выберите пункт Просмотреть код. Измените код метода Main , добавив входной параметр, который будет передаваться в конструктор службы:
static void Main(string[] args) < ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] < new MyNewService(args) >; ServiceBase.Run(ServicesToRun); >
Shared Sub Main(ByVal cmdArgs() As String) Dim ServicesToRun() As System.ServiceProcess.ServiceBase = New System.ServiceProcess.ServiceBase() System.ServiceProcess.ServiceBase.Run(ServicesToRun) End Sub
using System.Diagnostics; public MyNewService(string[] args) < InitializeComponent(); string eventSourceName = "MySource"; string logName = "MyNewLog"; if (args.Length >0) < eventSourceName = args[0]; >if (args.Length > 1) < logName = args[1]; >eventLog1 = new EventLog(); if (!EventLog.SourceExists(eventSourceName)) < EventLog.CreateEventSource(eventSourceName, logName); >eventLog1.Source = eventSourceName; eventLog1.Log = logName; >
Imports System.Diagnostics Public Sub New(ByVal cmdArgs() As String) InitializeComponent() Dim eventSourceName As String = "MySource" Dim logName As String = "MyNewLog" If (cmdArgs.Count() > 0) Then eventSourceName = cmdArgs(0) End If If (cmdArgs.Count() > 1) Then logName = cmdArgs(1) End If eventLog1 = New EventLog() If (Not EventLog.SourceExists(eventSourceName)) Then EventLog.CreateEventSource(eventSourceName, logName) End If eventLog1.Source = eventSourceName eventLog1.Log = logName End Sub
protected override void OnBeforeInstall(IDictionary savedState)
Protected Overrides Sub OnBeforeInstall(ByVal savedState As IDictionary) Dim parameter As String = "MySource1"" ""MyLogFile1" Context.Parameters("assemblypath") = """" + Context.Parameters("assemblypath") + """ """ + parameter + """" MyBase.OnBeforeInstall(savedState) End Sub
Сборка службы
- В обозревателе решений выберите пункт Свойства в контекстном меню проекта MyNewService. Отобразятся страницы свойств для проекта.
- На вкладке Приложение в списке Автоматически запускаемый объект выберите MyNewService.Program (или Sub Main для проекта Visual Basic).
- Чтобы выполнить сборку проекта, в обозревателе решений выберите в контекстном меню проекта пункт Сборка (или нажмите клавиши CTRL + SHIFT + B ).
Установка службы
После создания службы Windows ее можно установить. Чтобы установить службу Windows, необходимо иметь разрешения администратора на том компьютере, где выполняется установка.
- Откройте Командную строку разработчика Visual Studio с учетными данными администратора.
- В командной строке разработчика для Visual Studio перейдите к папке, которая содержит выходные данные проекта (по умолчанию это подкаталог \bin\Debug проекта).
- Введите следующую команду:
installutil MyNewService.exe
- Класс RunInstallerAttribute отсутствует в классе ProjectInstaller .
- Значение атрибута отличается от true .
- Класс ProjectInstaller не определен как public .
Запуск и выполнение службы

- В Windows откройте классическое приложение Службы. Нажмите клавиши Windows+R, чтобы открыть окно Выполнить, введите services.msc и нажмите клавишу ВВОД или кнопку ОК. Заданное вами отображаемое имя службы отобразится в списке Службы, представленном в алфавитном порядке.
- Чтобы запустить службу, в ее контекстном меню выберите пункт Запустить.
- Чтобы остановить службу, в ее контекстном меню выберите пункт Остановить.
- Для запуска и остановки службы в командной строке можно использовать команды net start и net stop (необязательно).
Проверка журнала событий для службы
- В Windows откройте классическое приложение Просмотр событий. Введите строку Просмотр событий в поле поиска Windows и выберите Просмотр событий в результатах поиска.
Совет В Visual Studio доступ к журналам событий можно получить, открыв обозреватель сервера в меню Вид (или нажав клавиши CTRL + ALT + S ) и развернув узел Журналы событий для локального компьютера.

Очистка ресурсов
Если приложение службы Windows вам больше не нужно, его можно удалить.
- Откройте Командную строку разработчика Visual Studio с учетными данными администратора.
- В окне Командная строка разработчика для Visual Studio перейдите к папке, которая содержит выходные данные проекта.
- Введите следующую команду:
installutil.exe /u MyNewService.exe
Следующие шаги
Теперь, после создания службы, можно выполнить указанные ниже действия.
- Создайте автономную программу установки, с помощью которой другие пользователи могут устанавливать вашу службу Windows. Создать установщик для службы Windows можно с помощью набора инструментов WiX. Другие идеи можно почерпнуть в статье о создании пакета установщика.
- Изучите возможности компонента ServiceController, который позволяет отправлять команды в установленную службу.
- Для создания журнала событий при установке приложения, а не во время его запуска, можно воспользоваться установщиком. В этом случае журнал событий удаляется установщиком при удалении приложения. Для получения дополнительной информации см. EventLogInstaller.
См. также
- Приложения служб Windows
- Знакомство с приложениями служб Windows
- Практическое руководство. Отладка приложений служб Windows
- Службы (Windows)
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Пилим свою службу 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. Скрипт будет предельно прост:
New-PolarisGetRoute -Path '/helloworld' -Scriptblock < $Response.Send('Hello World!') >Start-Polaris -Port 8080 while($true)

Работа так называемого «сервера».
Теперь попробуем превратить скрипт в службу. Для этого скачаем Windows Resource Kit Tools, где будут наши утилиты. Начнем с того, что установим пустой сервис командой:
instsrv WebServ C:\temp\rktools\srvany.exe
Где WebServ — имя нашего нового сервиса. При необходимости через оснастку services.msc можно задать пользователя, под которым будет запускаться служба, и разрешить взаимодействие с рабочим столом.
Теперь пропишем путь к нашему скрипту при помощи магии реестра. Параметры службы есть в разделе реестра HKLM\SYSTEM\CurrentControlSet\Services\WebServ. В нем нам нужно добавить новый раздел Parameters и создать там строковый параметр Application, указав в нем путь к исполняемому файлу. В случае скрипта PowerShell он будет выглядеть так:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoProfile -File C:\temp\Polaris\server.ps1

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

Работающая служба.
Однако у этого способа есть недостатки:
- Утилиты старые, разработаны до изобретения PowerShell, UAC и прочих вещей.
- Srvany не контролирует работу приложения. Даже если оно выпадет в ошибку, служба продолжит свое дело как ни в чем не бывало.
- Придется донастраивать и копаться в реестре. Вы же помните, что копаться в реестре небезопасно?
Поэтому перейдем к методу, частично лишенному этих проблем.
Способ второй, почти взрослый
Существует утилита под названием NSSM — Non-Sucking Service Manager, что можно перевести как не-плохой менеджер служб. В отличие от предыдущей, она поддерживается разработчиком, и исходный код опубликован на сайте. Помимо обычного способа, доступна и установка через пакетный менеджер Chocolately.
Создать сервис можно из обычной командной строки, вооружившись документацией на сайте разработчика. Но мы воспользуемся PowerShell. Потому что можем, разумеется.
$nssm = (Get-Command ./nssm).Source $serviceName = 'WebServ' $powershell = (Get-Command powershell).Source $scriptPath = 'C:\temp\Polaris\server.ps1' $arguments = '-ExecutionPolicy Bypass -NoProfile -File ""' -f $scriptPath & $nssm install $serviceName $powershell $arguments & $nssm status $serviceName Start-Service $serviceName Get-Service $serviceName

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

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

Настроить можно даже приоритет и использование ядер процессора.
Действительно, возможностей куда больше, чем у srvany и ряда других аналогов. Из минусов бросается в глаза недостаточный контроль над всем процессом.
Налицо нехватка «жести». Поэтому я перейду к самому хардкорному методу из всех опробованных.
Способ третий. AutoIT
Поскольку я давний любитель этого скриптового языка, то не смог пройти мимо библиотеки под названием _Services_UDF v4. Она снабжена богатой документацией и примерами, поэтому под спойлером сразу приведу полный текст получившегося скрипта.
Листинг скрипта
Итак, попробуем «завернуть» в нее наш веб-сервис:
#NoTrayIcon #RequireAdmin #Region #AutoIt3Wrapper_Version=Beta #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_Compile_Both=y #AutoIt3Wrapper_UseX64=y #EndRegion Dim $MainLog = @ScriptDir & "\test_service.log" #include #include $sServiceName="WebServ" If $cmdline[0] > 0 Then Switch $cmdline[1] Case "install", "-i", "/i" InstallService() Case "remove", "-u", "/u", "uninstall" RemoveService() Case Else ConsoleWrite(" - - - Help - - - " & @CRLF) ConsoleWrite("params : " & @CRLF) ConsoleWrite(" -i : install service" & @CRLF) ConsoleWrite(" -u : remove service" & @CRLF) ConsoleWrite(" - - - - - - - - " & @CRLF) Exit EndSwitch Else _Service_init($sServiceName) Exit EndIf Func _main($iArg, $sArgs) If Not _Service_ReportStatus($SERVICE_RUNNING, $NO_ERROR, 0) Then _Service_ReportStatus($SERVICE_STOPPED, _WinAPI_GetLastError(), 0) Exit EndIf $bServiceRunning = True $PID=Run("C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoProfile -File C:\temp\Polaris\server.ps1") While $bServiceRunning _sleep(1000) WEnd ProcessClose($PID) _Service_ReportStatus($SERVICE_STOP_PENDING, $NO_ERROR, 1000) DllCallbackFree($tServiceMain) DllCallbackFree($tServiceCtrl) _Service_ReportStatus($SERVICE_STOPPED, $NO_ERROR, 0) DllClose($hAdvapi32_DLL) DllClose($hKernel32_DLL) EndFunc Func _Sleep($delay) Local $result = DllCall($hKernel32_DLL, "none", "Sleep", "dword", $delay) EndFunc Func InstallService() #RequireAdmin Local $bDebug = True If $cmdline[0] > 1 Then $sServiceName = $cmdline[2] EndIf If $bDebug Then ConsoleWrite("InstallService("&$sServiceName &"): Installing service, please wait") _Service_Create($sServiceName, $sServiceName, $SERVICE_WIN32_OWN_PROCESS, $SERVICE_AUTO_START, $SERVICE_ERROR_SEVERE, '"' & @ScriptFullPath & '"');,"",False,"","NT AUTHORITY\NetworkService") If @error Then Msgbox("","","InstallService(): Problem installing service, Error number is " & @error & @CRLF & " message : " & _WinAPI_GetLastErrorMessage()) Else If $bDebug Then ConsoleWrite("InstallService(): Installation of service successful") EndIf Exit EndFunc Func RemoveService() _Service_Stop($sServiceName) _Service_Delete($sServiceName) If Not @error Then EndIf Exit EndFunc Func _exit() _Service_ReportStatus($SERVICE_STOPPED, $NO_ERROR, 0); EndFunc Func StopTimer() _Service_ReportStatus($SERVICE_STOP_PENDING, $NO_ERROR, $iServiceCounter) $iServiceCounter += -100 EndFunc Func _Stopping() _Service_ReportStatus($SERVICE_STOP_PENDING, $NO_ERROR, 3000) EndFunc
Разберу подробнее момент запуска приложения. Он начинается после операции $bServiceRunning = True и превращается в, казалось бы, бесконечный цикл. На самом деле этот процесс прервется, как только служба получит сигнал о завершении — будь то выход из системы или остановка вручную.
Поскольку программа для скрипта является внешней (powershell.exe), то после выхода из цикла нам нужно закончить ее работу с помощью ProcessClose.
Для этого скрипт необходимо скомпилировать в .exe, а затем установить службу, запустив exe с ключом -i.

Оно работает!
Разумеется, этот способ не самый удобный, и все дополнительные возможности придется реализовывать самостоятельно, будь то повторный запуск приложения при сбое или ротация логов. Но зато он дает полный контроль над происходящим. Да и сделать в итоге можно куда больше — от уведомления в Telegram о сбое службы до IPC-взаимодействия с другими программами. И вдобавок — на скриптовом языке, без установки и изучения Visual Studio.
Расскажите, а вам приходилось превращать скрипты и приложения в службы?
- служба windows
- autoit
- костыль или не совсем