Відмінність між сервісом та службою у віндовсі. Які служби у Windows потрібні, а які можна вимкнути. Служби Windows, які можна перевести в ручний режим роботи

Або робочим столом користувачів (як локальних, так і віддалених), однак для деяких служб можливий виняток - взаємодія з консоллю (сесією з номером 0, в якій зареєстрований користувач локально або під час запуску служби mstscіз ключем /console).

Існує кілька режимів для служб:

  • заборонено до запуску;
  • ручний запуск (за запитом);
  • автоматичний запуск під час завантаження комп'ютера;
  • автоматичний (відкладений) запуск (введений у Windows Vista та Windows Server 2008);
  • обов'язкова служба/драйвер (автоматичний запуск та неможливість (для користувача) зупинити службу).

Фоновий режим

Запуск, зупинення та зміна служб Windows

Служби та їх атрибути можуть бути змінені в консолі керування MMC:

У різних версіях операційних систем можуть бути одні служби та відсутні інші. Деякі програми та програми, які встановлюються окремо, також можуть створювати свої служби.

Список служб операційних систем Microsoft Windows

Ім'я, що виводиться Ім'я служби Функції Опис
DHCP-клієнт Dhcp Реєструє та оновлює IP-адреси та DNS-записи для цього комп'ютера. Якщо ця служба зупинена, комп'ютер не зможе отримувати динамічні IP-адреси та виконувати оновлення DNS.
DNS-клієнт Dnscache Служба DNS-клієнта (dnscache) кешує імена DNS (Domain Name System) та реєструє повне ім'я цього комп'ютера. Якщо службу зупинено, роздільна здатність імен DNS триватиме. Однак результати черг імен DNS не будуть кешуватися, а ім'я комп'ютера не буде зареєстровано.
KtmRm для координатора розподілених транзакцій KtmRm Координує транзакції між MSDTC та диспетчером транзакцій ядра (Kernel Transaction Manager – KTM).
ReadyBoost EMDMgmt ReadyBoost Підтримка підвищення продуктивності системи за допомогою технології ReadyBoost.
Superfetch SysMain Superfetch Підтримує та покращує продуктивність системи.
Windows Audio Audiosrv Керування засобами роботи зі звуком для Windows. Якщо цю службу зупинено, аудіопристрої та ефекти не будуть правильно працювати.
Windows CardSpace idsvc Забезпечує надійну можливість створення, керування та розкриття цифрових посвідчень.
Автоматичне оновлення WUAUSERV Включає завантаження та встановлення оновлень Windows. Якщо службу вимкнено, то на цьому комп'ютері неможливо використовувати можливості автоматичного оновленняабо веб-сайт Windows Update.
Віддалений виклик процедур (RPC) RpcSs Забезпечує зіставлення кінцевих точок та інших служб RPC.

Список служб, створюваних програмами та програмами Microsoft

Приклади служб, створюваних програмами та програмами інших виробників

Ім'я, що виводиться Ім'я служби Функції Опис
ESET HTTP Server EhttpSrv антивірусний захист ESET HTTP Server, компонент

Чи можна запустити клієнтську програму як службу? Не кожна консольна програма зможе запуститися як служба, а програми з графічним інтерфейсом в принципі не вміють працювати подібним чином. Але можливість запустити додаток як службу все ж таки є, і допоможе нам у цьому програма з оригінальною назвою Non-Sucking Service Manager.

NSSM являє собою вільне програмне забезпечення з відкритим кодомта підтримує всі операційні системи Microsoftпочинаючи з Windows 2000 і закінчуючи. NSSM не вимагає установки, достатньо його завантажити та розпакувати. У дистрибутив входять версії для 32- та 64-розрядних ОС. Взяти програму можна із сайту nssm.cc, на Наразіостання стабільна версія 2.21.1, яку я буду використовувати.

Для демонстрації можливостей NSSM спробуємо запустити Блокнот як службу на .

Створення служби

Для створення служби з ім'ям notepadзапускаємо командну консоль, переходимо до папки з розпакованим NSSM (для 64-розрядної Windows) і вводимо команду nssm install notepad, яка відкриває вікно графічного інсталятора NSSM. Щоб створити службу, достатньо в полі Path вказати шлях до файлу і натиснути кнопку "Install service". Додатково в полі Options можна вказати ключі, потрібні для запуску служби.

Також на етапі створення нової служби можна зазначити деякі додаткові параметри.

На вкладці "Shutdown" перераховані методи зупинки та таймаути, які використовуються при штатному завершенні роботи або аварійній зупинці програми. Коли NSSM отримує команду зупинки (напр. при завершенні роботи програми), він намагається зупинити контрольований додаток штатним чином. Якщо ж програма не відповідає, то NSSM може примусово завершити всі процеси та підпроцеси цієї програми.

Усього є чотири етапи завершення роботи програми, і за умовчанням вони використовуватимуться в такому порядку:

На першому етапі NSSM намагається згенерувати та відправити подію Ctrl+C.Цей спосіб добре працює для консольних додатків або скриптів, але не застосовується для графічних додатків;
Потім NSSM визначає всі вікна, створені програмою, і надсилає їм повідомлення WM_CLOSE, що ініціює вихід із програми;
Третім етапом NSSM обчислює всі потоки, створені програмою, і надсилає їм повідомлення WM_QUIT, яке буде отримано, якщо програма має чергу повідомлень потоку;
І як останній засіб NSSM може викликати метод TerminateProcess(), примусово завершивши роботу програми.

Можливо відключити деякі або навіть усі методи, однак для різних програм спрацьовують різні методи і для коректного завершення роботи програми рекомендується залишити все як є.

За умовчанням під час падіння служби NSSM намагається рестартувати її. На вкладці "Exit actions" можна змінити автоматичну дію під час нештатного завершення роботи програми, а також виставити затримку перед автоматичним перезапуском програми.

На вкладці "Input/Output (I/O)" можна задати перенаправлення введення\виводу програми у вказаний файл.

На вкладці "Environment" можна встановити нові змінні оточення або перевизначити існуючі.

Також можна не користуватися графічною оболонкою і одразу створити службу в консолі такою командою:

nssm install notepad C:\Windows\system32\notepad.exe

Управління службою

Після створення служби за допомогою NSSM зайдемо в оснастку Services та знайдемо службу notepad. Як бачите, на вигляд вона нічим не відрізняється від інших служб, ми також можемо її запустити, зупинити або змінити режим запуску. Однак зверніть увагу, що як виконуваний файл вказано nssm.exe.

А якщо зайти в Task Manager, то ми побачимо наступну картину: як основний (батьківський) процес запущено NSSM, служба notepad запущена як його дочірній процес, і вже в цьому дочірньому процесі запущено додаток Блокнот.

Видалення служби

Для видалення служби вводимо команду nssm remove notepad та підтверджуємо її видалення. А ввівши команду nssm remove notepad confirm можна обійтися і без підтвердження.

Запуск служби в інтерактивному режимі

Основна відмінність програми користувача від служби полягає в тому, що після запуску програма може вимагати для продовження роботи додаткових дій з боку користувача - наприклад натиснути кнопку або ввести команду. Для цього необхідно отримати до нього доступ, що як виявляється, не так просто зробити.

Для того, щоб запустити службу в інтерактивному режимі, треба в оснастці Служби відкрити її властивості і на вкладці "Вхід до системи" відзначити чекбокс "Дозволити взаємодію з робочим столом".

А далі починаються дива Для служби, запущеної в інтерактивному режимі система відкриває окремий ізольований сеанс (session 0). Потрапити в цей сеанс можна лише за допомогою служби виявлення інтерактивних служб (ui0detect), яка відстежує запуск інтерактивних служб на комп'ютері та видає оповіщення. У Windows 7\Server 2008 ця служба активна за замовчуванням, а у Windows 8\Server 2012 вона відключена і не відображається в графічному оснащенні Служби (принаймні я її там не знайшов). Більше того, якщо ви все ж таки знайдете цю таємничу службу і спробуєте її запустити, то отримаєте повідомлення про помилку.

Справа в тому, що для її запуску необхідно дозволити запуск інтерактивних служб на комп'ютері. Тому відкриваємо редактор реєстру, знаходимо в розділі HKLM\System\CurrentControlSet\Control\Windows параметр типу DWORD з ім'ям NoInteractiveServicesі ставимо його значення в 0 .

Після чого відкриваємо консоль PowerShell та стартуємо службу виявлення командою:

Start-Service -Name ui0detect

Переконавшись, що служба виявлення запущена, рестартуємо службу notepad, і отримуємо ось таке віконце. Вибираємо пункт "Подивитися повідомлення"

і потрапляємо в нульовий сеанс, в якому працює наша програма. Далі робимо з ним необхідні дії і повертаємося назад.

Таке ось цікаве рішення для запуску програм у вигляді служб Windows. Не найкрасивіше, але цілком відповідне своїй назві


Служба Windows NT (Windows NT service) - спеціальний процес, що має уніфікований інтерфейс для взаємодії з операційною системою Windows NT. Служби поділяються на два типи - служби Win32, що взаємодіють з операційною системою за допомогою диспетчера управління службами (Service Control Manager - SCM), та драйвера, що працюють за протоколом драйвера пристрої Windows NT. Далі в цій статті ми будемо обговорювати лише служби Win32.

Застосування служб

Однією з найважливіших властивостей служби є неінтерактивність. Типове служби - це непомітна для звичайного користувачаробота в фоновому режимі. В силу цієї служби найбільше підходять для реалізації наступних типів додатків:

  • Сервера в архітектурі клієнт-сервер (наприклад, MS SQL, MS Exchange Server)
  • Мережеві служби Windows NT (Server, Workstation);
  • Серверні (в сенсі функціональності) компоненти розподілених програм (наприклад, всілякі програми моніторингу).

Основні властивості служб

Від звичайної програми Win32 службу відрізняють три основні властивості. Розглянемо кожне з них.

По-перше, це можливість коректного зупину (пріостанова) роботи служби. Користувач або інший додаток, що використовують стандартні механізми, мають можливість змінити стан служби - перевести її зі стану виконання стан паузи або навіть зупинити її роботу. При цьому служба перед зміною свого стану отримує спеціальне повідомлення, завдяки якому може здійснити необхідні переходу в новий стан дії, наприклад, звільнити зайняті ресурси.

По-друге, можливість запуску служби до реєстрації користувача та, як наслідок, можливість роботи взагалі без зареєстрованого користувача. Будь-яка служба може бути запущена автоматично при старті операційної системи та розпочати роботу ще до того, як користувач здійснить вхід до системи.

І, нарешті, можливість роботи у довільному безпековому контексті. Контекст безпеки Windows NT визначає сукупність прав доступу процесу до різних об'єктів системи та даних. На відміну від звичайної програми Win32, яка завжди запускається в контексті безпеки користувача, зареєстрованого на даний момент у системі, для служби контекст безпеки її виконання можна визначити заздалегідь. Це означає, що для служби можна визначити набір прав доступу до об'єктів системи заздалегідь і тим самим обмежити сферу її діяльності. Стосовно служб існує спеціальний вид контексту безпеки, що використовується за умовчанням і називається Local System. Служба, запущена в цьому контексті, має права лише на ресурси локального комп'ютера. Ніякі мережеві операції не можуть бути здійснені з правами Local System, оскільки цей контекст має сенс тільки на локальному комп'ютеріі не розпізнається іншими комп'ютерами мережі.

Взаємодія служби з іншими програмами

Будь-яка програма, яка має відповідні права, може взаємодіяти зі службою. Взаємодія, в першу чергу, передбачає зміну стану служби, тобто переведення її в один із трьох станів - працююче (Запуск), призупинення (Пауза), зупинка та здійснюється за допомогою подачі запитів SCM. Запити бувають трьох типів - повідомлення від служб (фіксація їх станів), запити, пов'язані зі зміною конфігурації служби або отриманням інформації про неї та запити програм на зміну стану служби.

Для управління службою необхідно в першу чергу одержувати її дескриптор за допомогою функції Win32 API OpenService. Функція StartService запускає службу. У разі потреби зміна стану служби здійснюється викликом функції ControlService.

База даних служби

Інформація про кожну службу зберігається в реєстрі - у ключі HKLM\SYSTEM\CurrentControlSet\Services\ServiceName. Там містяться такі відомості:

  • Тип служби. Вказує на те, чи реалізована в цьому додатку лише одна служба (ексклюзивна) або їх у додатку кілька. Ексклюзивна служба може працювати у будь-якому контексті безпеки. Декілька служб всередині однієї програми можуть працювати тільки в контексті LocalSystem.
  • Тип запуску. Автоматичний – служба запускається при старті системи. На вимогу – служба запускається користувачем вручну. Деактивований – служба не може бути запущена.
  • Ім'я модуля, що виконується (EXE-файл).
  • Порядок запуску до інших служб. У деяких випадках для коректної роботи служби потрібно запустити одну або кілька інших служб. У цьому випадку реєстр містить інформацію про служби, що запускаються перед даною.
  • Контекст безпеки виконання служби (ім'я мережі та пароль). За промовчанням контекст безпеки відповідає LocalSystem.

Програми, яким потрібно отримати інформацію про якусь службу або змінити той чи інший параметр служби, по суті повинні змінити інформацію в базі даних служби в реєстрі. Це можна зробити за допомогою відповідних функцій Win32 API:

  • OpenSCManager, CreateService, OpenService, CloseServiceHandle – для створення (відкриття) служби;
  • QueryServiceConfig, QueryServiceObjectSecurity, EnumDependentServices, EnumServicesStatus - для отримання інформації про службу;
  • ChangeServiceConfig, SetServiceObjectSecurity, LockServiceDatabase, UnlockServiceDatabase, QueryServiceLockStatus - зміни конфігураційної інформації служби.

Внутрішній пристрій.

Для того, щоб додаток повинен бути влаштований відповідним чином, а саме - включати певний набір функцій (в термінах C++) з певною функціональністю. Розглянемо коротко кожну їх.

Функція main

Як відомо, функція main - точка входу будь-якого консольного Win32 програми. При запуску служби насамперед починає виконуватися код цієї функції. Протягом 30 секунд з моменту старту функція main повинна обов'язково викликати StartServiceCtrlDispatcher для встановлення з'єднання між програмою та SCM. Усі комунікації між будь-якою службою цього додаткута SCM здійснюються всередині функції StartServiceCtrlDispatcher, яка завершує роботу лише після зупинки всіх служб у програмі.

Функція ServiceMain

Крім загальнопроцесної точки входу існує ще окрема точка входу кожної зі служб, реалізованих у додатку. Імена функцій, що є точками входу служб (для простоти назвемо їх всіх однаково - ServiceMain), передаються SCM в одному з параметрів під час виклику StartServiceCtrlDispatcher. При запуску кожної служби для виконання ServiceMain створюється окремий потік.

Отримавши керування, ServiceMain перш за все має зареєструвати обробник запитів до служби, функцію Handler, свою для кожної служби в додатку. Після цього ServiceMain зазвичай слідують якісь дії для ініціалізації служби - виділення пам'яті, читання даних тощо. Ці дії повинні обов'язково супроводжуватись повідомленнями SCM про те, що служба все ще знаходиться в процесі старту і жодних збоїв не сталося. Повідомлення надсилаються за допомогою викликів функції SetServiceStatus. Всі виклики, крім останнього, повинні бути з параметром SERVICE_START_PENDING, а останній - з параметром SERVICE_RUNNING. Періодичність викликів визначається розробником служби, виходячи з наступних умов: тривалість тимчасового інтервалу між двома сусідніми викликами SetServiceStatus не повинна перевищувати значення параметра dwWaitHint, переданого SCM при першому з двох викликів. А якщо ні, то SCM, не отримавши в час чергового повідомлення, примусово зупинить службу. Такий спосіб дозволяє уникнути ситуації служби на старті внаслідок виникнення тих чи інших збоїв (згадаймо, що служби зазвичай не інтерактивні і можуть запускатися без користувача). Звичайна практика у тому, що після завершення чергового кроку ініціалізації відбувається повідомлення SCM.

Функція Handler

Як згадувалося вище, Handler - це прототип callback-функции, обробника запитів до служби, своєї кожної служби у додатку. Handler викликається, коли службі надходить запит (запуск, призупинення, відновлення, зупинка, повідомлення поточного стану) та виконує необхідні відповідно до запиту дії, після чого повідомляє новий стан SCM.

Один запит слід відзначити особливо - запит, що надходить після завершення роботи системи (Shutdown). Цей запит сигналізує про необхідність виконати деініціалізацію та завершитися. Microsoft стверджує, що для завершення роботи кожній службі виділяється 20 секунд, після чого вона примусово зупиняється. Проте тести показали, що це умова виконується який завжди і служба примусово зупиняється до закінчення цього часу.

Система безпеки служб

Будь-яка дія над службами потребує відповідних прав у додатку. Всі програми мають права на з'єднання з SCM, перерахування служб і перевірку заблокованості БД служби. Зареєструвати в системі нову службу або блокувати БД служби можуть тільки програми, які мають адміністративні права.

Кожна служба має дескриптор безпеки, який описує, які користувачі мають права на ту чи іншу операцію. За замовчуванням:

  • Всі користувачі мають права SERVICE_QUERY_CONFIG, SERVICE_QUERY_STATUS, SERVICE_ENUMERATE_DEPENDENTS, SERVICE_INTERROGATE та SERVICE_USER_DEFINED_CONTROL;
  • Користувачі, що входять до групи Power Users та обліковий запис LocalSystem додатково мають права SERVICE_START, SERVICE_PAUSE_CONTINUE та SERVICE_STOP;
  • Користувачі, що входять до груп Administrators та System Operators, мають право SERVICE_ALL_ACCESS.

Служби та інтерактивність

За промовчанням інтерактивні служби можуть виконуватись лише у контексті безпеки LocalSystem. Це пов'язано з особливостями виведення на екран монітора в Windows NT, де існує, наприклад, такий об'єкт як "Desktop", для роботи з яким потрібно мати відповідні права доступу, яких може не виявитись у довільній облікового запису, відмінний від LocalSystem. Незважаючи на те, що в переважній більшості випадків це обмеження є несуттєвим, однак іноді існує необхідність створити службу, яка виводила б інформацію на екран монітора і при цьому виконувалася б у контексті безпеки відмінному від LocalSystem, наприклад, серверна компонента програми для запуску програм на віддаленому комп'ютері.

Фрагмент коду. ілюструє таку можливість.

У цьому фрагменті у відповідь на запит, надісланий частиною програми наслідком RPC, служба виводить текстове повідомлення на екран монітора.

Приклад служби (ключові фрагменти)

Розглянемо з прикладу ключові фрагменти докладання мовою З++, реалізує службу Windows NT. Для наочності несуттєві частини коду опущені.

Функція main

В показаний код функції main.

Функція ServiceMain

Особливістю коду, що міститься в ServiceMain, є те, що часто неможливо заздалегідь передбачити час виконання тієї чи іншої операції, особливо якщо врахувати, що її виконання відбувається в операційній системі з багатозадачністю, що витісняє. Якщо операція триватиме довше за вказаний у параметрі виклику SetServiceStatus інтервал часу, служба не зможе вчасно надіслати наступне повідомлення, внаслідок чого SCM зупинить її роботу. Прикладами потенційно операцій можуть бути виклики функцій роботи з мережею при великих таймаутах або одноразове читання великої кількості інформації з повільного носія. Крім того, такий підхід абсолютно не застосовний при налагодженні служби, оскільки виконання програми у налагоджувальному апараті супроводжується великими паузами, необхідними розробнику.

Для подолання цієї проблеми всі операції із взаємодії з SCM слід виконувати в окремому потоці, який не залежить від дій, що відбуваються на етапі ініціалізації.

У показаний алгоритм коректного запуску служби, який використовує допоміжний потік.

Функція Handler

У показаний код функції Handler та допоміжних потоків. Для запитів "Stop" та "Shutdown" використовується алгоритм коректного зупинки служби, аналогічний тому, що використовується при старті служби, з тією різницею, що замість параметра SERVICE_START_PENDING у SetserviceStatus передається параметр SERVICE_STOP_PENDING, а замість SERVICE_RUNNING - SERVICE_STOPPED.

В ідеалі для запитів "Pause" та "Continue" також слід використовувати цей підхід. Допитливий читач легко зможе реалізувати його, спираючись на дані приклади.

Висновок

На закінчення хотілося б відзначити, що з переходом на Windows NT 2000 розробка служб не зазнала змін. Служби, як і раніше, залишаються важливою частиною програмного забезпеченняна платформі Windows, що надає розробникам широке поле діяльності.


// Функція, аналог MessageBox Win32 API int ServerMessageBox(RPC_BINDING_HANDLE h, LPSTR lpszText, LPSTR lpszTitle, UINT fuStyle) (DWORD dwThreadId; HWINSTA hwinstaSave; HDesk " і "Desktop". GetDesktopWindow(); hwinstaSave = GetProcessWindowStation(); dwThreadId = GetCurrentThreadId(); hdeskSave = GetThreadDesktop(dwThreadId); // Змінюємо контекст безпеки на той, // який є у до користувальницьких // об'єктів "Window station" і "Desktop". RpcImpersonateClient(h); hwinstaUser), hdeskUser = OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED); RpcRevertToSelf(); urn 0; ) SetThreadDesktop(hdeskUser); // Виводимо стандартне текстове вікно. result = MessageBox(NULL, lpszText, lpszTitle, fuStyle); // Відновлюємо збережені об'єкти // "Window station" та "Desktop". SetThreadDesktop(hdeskSave); SetProcessWindowStation(hwinstaSave); CloseDesktop(hdeskUser); CloseWindowStation(hwinstaUser); return result; ) void main() ( SERVICE_TABLE_ENTRY steTable = ( (SERVICENAME, ServiceMain), (NULL, NULL) ); // Встановлюємо з'єднання з SCM. Усередині цієї функції // відбувається прийом і диспетчеризація запитів. StartServiceCtrlDispatcher(steTable); ) void WINAPI ServiceMain (DWORD dwArgc, LPSTR *psArgv) ( // Сразу регистрируем обработчик запросов. hSS = RegisterServiceCtrlHandler(SERVICENAME, ServiceHandler); sStatus.dwCheckPoint = 0; sStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE; sStatus.dwServiceSpecificExitCode = 0; sStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS sStatus.dwWaitHint = 0 sStatus.dwWin32ExitCode = NOERROR // Для ініціалізації служби викликається функція InitService(); , Що служба в процесі ініціалізації.// Для синхронізації потоку створюється подія.// Після цього запускається робочий потік, д ля // синхронізації якого // створюється подія. hSendStartPending = CreateEvent(NULL, TRUE, FALSE, NULL); HANDLE hSendStartThread; DWORD dwThreadId; hSendStartThread = CreateThread(NULL, 0, SendStartPending, NULL, 0, &dwThreadId); //Тут проводиться вся ініціалізація служби. InitService(); SetEvent(hSendStartPending); if(WaitForSingleObject(hSendStartThread, 2000) != WAIT_OBJECT_0) ( TerminateThread(hSendStartThread, 0); ) CloseHandle(hSendStartPending); CloseHandle(hSendStartThread); hWork = CreateEvent(NULL, TRUE, FALSE, NULL); hServiceThread = CreateThread(NULL, 0, ServiceFunc, 0, 0, &dwThreadId); sStatus.dwCurrentState = SERVICE_RUNNING; SetServiceStatus(hSS, &sStatus); ) // Функція потоку, що секунду посилає повідомлення SCM // про те, що процес ініціалізації йде. Робота функції // завершується, коли встановлюється // подія hSendStartPending. DWORD WINAPI SendStartPending(LPVOID) ( sStatus.dwCheckPoint = 0; sStatus.dwCurrentState = SERVICE_START_PENDING; sStatus.dwWaitHint = 2000; // "Засипаємо" на 1 секунду. Якщо на 1 секунду // в ініціалізація служби не // закінчилася), надсилаємо чергове повідомлення, // встановивши максимальний інтервал часу // в 2 секунди, для того, щоб був запас часу до // наступного повідомлення: while (true) .dwCheckPoint++;if(WaitForSingleObject(hSendStartPending, 1000)!=WAIT_TIMEOUT) break; ) sStatus.dwCheckPoint = 0; return 0; ) // Функція, що ініціалізує службу. Читання даних // розподіл пам'яті і т.п. void InitService() (...) // Функція, що містить код служби. DWORD WINAPI ServiceFunc(LPVOID) ( while (true) ( ​​if (!bPause) ( // Тут міститься код, який зазвичай // виконує якісь циклічні операції... ) if (WaitForSingleObject(hWork, 1000)!=WAIT_TIMEOUT ) Break; ) return 0; TRUE, FALSE, NULL), hSendStopThread = CreateThread(NULL, 0, SendStopPending, NULL, 0, & dwThreadId); ) SetEvent(hSendStopPending), CloseHandle(hServiceThread), CloseHandle(hWork); ServiceStatus(hSS, &sStatus); break; case SERVICE_CONTROL_PAUSE: bPause = true; sStatus.dwCurrentState = SERVICE_PAUSED; SetServiceStatus(hSS, &sStatus); break; case SERVICE_CONTROL_CONTINUE: bPause=true; sStatus.dwCurrentState = SERVICE_RUNNING; SetServiceStatus(hSS, &sStatus); break; case SERVICE_CONTROL_INTERROGATE: SetServiceStatus(hSS, &sStatus); break; default: SetServiceStatus(hSS, &sStatus); break; ) ) // Функція потоку, аналогічна SendStartPending // для зупинки служби. DWORD WINAPI SendStopPending(LPVOID) ( sStatus.dwCheckPoint = 0; sStatus.dwCurrentState = SERVICE_STOP_PENDING; =WAIT_TIMEOUT) break;) sStatus.dwCheckPoint = 0; return 0;)

Як запустити програму у вигляді служби Windows



Чи можна запустити клієнтську програму як службу? В одній із статей способи створення служби Windows штатними засобами ОС. Однак, не кожен консольний додаток зможе запуститися як служба, а програми з графічним інтерфейсом в принципі не вміють працювати подібним чином. Але можливість запустити додаток як службу все ж таки є, і допоможе нам у цьому програма з оригінальною назвою Non-Sucking Service Manager.

NSSM являє собою вільне програмне забезпечення з відкритим кодом та підтримує всі операційні системи Microsoft, починаючи з Windows 2000 і до Windows 8. NSSM не вимагає установки, достатньо його завантажити і розпакувати. У дистрибутив входять версії для 32- та 64-розрядних ОС. Взяти програму можна з сайту nssm.cc, на даний момент остання стабільна версія 2.21.1, яку я буду використовувати.
Для демонстрації можливостей NSSM спробуємо запустити Блокнот Windows як службу Windows 8.1.

Створення служби

Для створення служби з ім'ям notepadзапускаємо командну консоль, переходимо в папку з розпакованим NSSM (для 64-розрядної Windows) та вводимо команду

Код:

Nssm install notepad

яка відкриває вікно графічного інсталятора NSSM. Щоб створити службу, достатньо в полі Path вказати шлях до файлу і натиснути кнопку «Install service». Додатково в полі Options можна вказати ключі, які необхідні для запуску служби.

Також на етапі створення нової служби можна зазначити деякі додаткові параметри.

На вкладці Shutdown перераховані методи зупинки та тайм-аути, які використовуються при штатному завершенні роботи або аварійній зупинці програми. Коли NSSM отримує команду зупинки (напр. при завершенні роботи програми), він намагається зупинити контрольований додаток штатним чином. Якщо ж програма не відповідає, то NSSM може примусово завершити всі процеси та підпроцеси цієї програми.

Усього є чотири етапи завершення роботи програми, і за умовчанням вони використовуватимуться в такому порядку:

На першому етапі NSSM намагається згенерувати та надіслати подію Ctrl+C. Цей спосіб добре працює для консольних додатків або скриптів, але не застосовується для графічних додатків;
Потім NSSM визначає всі вікна, створені програмою, і надсилає їм повідомлення WM_CLOSE, що ініціює вихід із програми;
Третім етапом NSSM обчислює всі потоки, створені програмою, і надсилає їм повідомлення WM_QUIT, яке буде отримано, якщо програма має чергу повідомлень потоку;
І як останній засіб NSSM може викликати метод TerminateProcess(), примусово завершивши роботу програми.

Можливо відключити деякі або навіть усі методи, однак для різних програм спрацьовують різні методи і для коректного завершення роботи програми рекомендується залишити все як є.

За умовчанням під час падіння служби NSSM намагається рестартувати її. На вкладці Exit actions можна змінити автоматичну дію при нештатному завершенні роботи програми, а також виставити затримку перед автоматичним перезапуском програми.

На вкладці «Input/Output (I/O)» можна задати перенаправлення вводу/виводу програми у вказаний файл.

На вкладці «Environment» можна встановити нові змінні оточення для служби або перевизначити існуючі.

Також можна не користуватися графічною оболонкою і одразу створити службу в консолі такою командою:

Код:

Nssm install notepad "C:\Windows\system32\notepad.exe"

Управління службою

Після створення служби за допомогою NSSM зайдемо в оснастку Services та знайдемо службу notepad. Як бачите, на вигляд вона нічим не відрізняється від інших служб, ми також можемо її запустити, зупинити або змінити режим запуску. Однак зверніть увагу, що як виконуваний файл вказано nssm.exe.

А якщо зайти в Task Manager, то ми побачимо наступну картину: як основний (батьківський) процес запущено NSSM, служба notepad запущена як його дочірній процес, і вже в цьому дочірньому процесі запущено додаток Блокнот.

З погляду програмної сумісності. Тому цілком природно, що ми повертаємося до обговорення служб у контексті Windows 7. Але цього разу ми поговоримо про деякі вигоди оптимізації служб, доступних у Windows 7. Ця стаття присвячена новій можливості Windows 7 – Trigger Start Services. Але перш, ніж звернутися до API, давайте окреслимо загальну картину служб.

Що таке служба?

Служба - це внутрішній механізм, вбудований в операційну систему Windows. Ви можете вважати служби спеціальними програмами, що працюють незалежно від поточного контексту користувача. Служби відрізняються від звичайних програм тим, що її можна настроїти на роботу з моменту ввімкнення (завантаження) системи і до вимкнення, не вимагаючи присутності користувача. Тобто служби можуть працювати, навіть якщо користувач не виконав вхід до системи.

Ми вважаємо за краще вважати служби запущеними завданнями, що працюють у фоновому режимі і не торкаються операцій користувача. Служби Windows відповідають за всі види фонової активності, починаючи з Remote Procedure Call (RPC), Printer Spooler і аж до Network Location Awareness.

Протягом багатьох років Windows зростала і водночас збільшувалася кількість служб. Будемо чесні, фонові служби у Windows відчуваються досить болісно – операційна системаспочатку поставляється з безліччю служб. Крім того, незалежні розробники програмного забезпечення (ISV) та їхні програми додають ще більше служб. Наприклад, служби оновлення програмного забезпечення. Разом з тим, деякі служби критично важливі і потрібні в процесі завантаження, в той час як необхідність інших виникає пізніше, коли певний користувач виконує вхід в систему, а інші зовсім не потребують запуску, поки не будуть викликані. Незважаючи на це, коли ви переглядаєте список запущених в даний момент служб, бачите безліч об'єктів, яким немає необхідності працювати за схемою 24х7.

Що поганого у службах, що працюють 24 години на добу 7 днів на тиждень?

Є кілька проблем, пов'язаних із службами, що працюють за схемою 24х7. По-перше, навіщо щось має працювати (хай навіть у фоновому режимі), якщо в ньому немає потреби? Будь-який запущений процес (включаючи служби) використовує дорогоцінну пам'ять та ресурси ЦП, які могли б використовуватися для інших програм та служб. Якщо ви підрахуєте всі служби, запущені в певний момент, вони складуться у значний обсяг пам'яті, дескрипторів, потоків і використання ЦП. Всі ці «витратні» ресурси знижують загальну продуктивність комп'ютера, його чуйність і справляють враження, що комп'ютер млявий і повільний. До того ж, оскільки багато служб налаштовані на автоматичний запуск (починають працювати під час старту системи), вони впливають на час завантаження комп'ютера.

По-друге, ці розтрачувані ресурси безпосередньо позначаються на споживанні електроенергії. Чим більше навантаженняна ЦП, тим більше електроенергії споживає комп'ютер. Це може бути важливо для ноутбуків і може скоротити час роботи від батареї на кілька годин.

По-третє, постійна робота непродуктивного програмного забезпечення може призвести до витоків пам'яті та загальної нестабільності системи. Це веде до збою в роботі програм і, нарешті, комп'ютера.

Нарешті, якщо служба працює за схемою 24х7, і якщо це добре відома служба (яка може виявитися у кожної популярної програми – наприклад, у PDF Reader), це створює велику поверхню для атаки. Зловмисник може скористатися відомостями про те, що певна популярна програма встановлює службу, що працює в режимі 24х7, і спробувати зламати її для отримання доступу до комп'ютера.

Враховуючи все вищесказане, ви можете здивуватися, чому так багато розробників налаштовують свої служби на постійну роботу, якщо вони мають іншу можливість. Навіть до Windows 7 було доступно кілька варіантів запуску служб:

  • Disabled (Вимкнено)повністю відключає службу та запобігає її запуску та запуску залежних служб – це означає, що користувач повинен включити службу вручну з панелі керування або командного рядка
  • Manual (Вручну)запускає службу потреби (у зв'язку з залежностями інших служб) або при виклику служби з програми за допомогою відповідних API, як буде показано нижче
  • Automatic (Автоматично)запускає службу при вході до системи
  • Automatic Delayed (Автоматичний відкладений запуск)– новий тип запуску, що з'явився в Windows Vista, за допомогою якого запуск служби відбувається після завершення завантаження та виконання початкових операцій, що прискорює запуск системи.

На жаль, багато ISV (включаючи саму корпорацію Microsoft) продовжують налаштовувати свої служби на автоматичний (Automated) або автоматичний відкладений запуск (Automatic Delayed), оскільки для всіх є найпростішим рішенням. Служба просто працює 24х7 і завжди доступна, усуваючи будь-яку необхідність перевірки залежностей або запущена служба.

Можна навести безліч прикладів існуючих служб, які можуть витрачати значно менше ресурсів і стати безпечнішими, не працюючи в режимі 24х7. Наприклад, подумайте про службу оновлень, яка перевіряє наявність нових оновлень для програми. Якщо комп'ютер не підключений до мережі та не має IP-адреси, то навіщо їй працювати? Вона нічого не може зробити, то навіщо залишати працюючу програму, яка нічого не робить? Подумайте про службу управління політиками, яка використовується під час зміни групових політикабо при підключенні комп'ютера до домену або відключенні від нього, але зараз, коли комп'ютер підключено до моєї домашньої мережі, служба знову ж таки працює марно.

Поява служб із запуском по тригеру

Вирішення вищевказаних проблем полягає у виведенні служби зі стану постійної роботи» інші види фонової активності, такі як заплановані завдання або служби, що запускаються тригером. Ця стаття присвячена Windows 7 Trigger Start Services. Про Windows 7 Scheduled Tasks можна сказати дуже багато цікавого, що буде зроблено в наступних статтях.

Принтери