Программное установление службы 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Программное установление службы



Перед тем как служба станет доступна для менеджера служб, ее нужно установить в системе. Установление сводится к заносу соответствующей информации в системный реестр, его можно делать в отдельном приложении и в коде самой службы, например во время вызова ее выполняемого файла с определенным параметром командной строки. Для установления службы используют функцию CreateService():

Sc_handle CreateService(Sc_handle mh. LPCTSTR svc_name.

LPCTSTR disp_name. DWORD access. DWORD svc_type. DWORD start_type

DWORD err_ctl. LPCTSTR exe_path, LPCTSTR lgrp. LPDWORD tag_id

LPCTSTR deps. LPCTSTR account. LPCTSTR password);

где: mh - дескриптор менеджера служб, полученный с помощью вызова функции OpenSCManager();

svc_name - имя службы, используемое для ее идентификации (в частности, его передают в функции управления службами, оно является параметром утилиты net. exe и тому подобное);

disp_name - имя, занесенное в списке служб окна управления службами, а также в сообщениях утилиты net. exe;

svc_type - тип службы (для обычных служб, выполняемых в отдельном процессе, используют значение SERVICE_WIN32_OWN_PR0CESS);

start_type - тип запуска службы (SERVICE_DEMAND_START - запуск по требованию,

SERVICE_AUTO_START - автоматический запуск во время загрузки системы);

exe_path - полный путь к выполняемому файлу службы (если службу устанавливают из ее собственного кода, для получения такого пути можно использовать функцию GetmoduleFileName());

account - имя пользователя, с правами которого будет выполняться служба (если NULL - службу выполняют с правами специального пользователя Local System, так делают чаще всего), password - пароль этого пользователя.

Функция возвращает дескриптор службы. После завершения работы со службой этот дескриптор нужно закрыть с помощью функции CloseServiceHandle().

char exe_path[1024]:

GetModuleFileName(NULL, exe_path. sizeof(exe_path)):

SC_HANDLE mh - OpenSCManager(NULL.NULL.SC_MANAGER_ALL_ACCESS);

SC_HANDLE sh = CreateService(mh."mysvc"."Служба MySvc".

SERVICE_ALL ACCESS. SERVICE_WIN32_OWN_ PROCESS, SERVICE_DEMAND_START.

SERVICE_EROR_NORMAL. exe_path. NULL. NULL. NULL. NULL. NULL);

CloseServiceHandle (sh);

Реализация кода службы

Перейдем к непосредственной реализации кода службы. В первую очередь необходимо определить несколько переменных. Среди них структура SERVICE_STATUS, которая отображает состояние службы, дескриптор состояния службы (переменная типа Service_status_handle) и флажок, который определяет, можно ли продолжать выполнение основной функции службы (переменная running). Эти переменные определяются как глобальные, потому что к ним нужен доступ из нескольких функций (главной функции службы и обработчика команд управления).

SERVICE_STATUS status = { 0 }:

SERVICE_STATUS_HANDLE sth;

bool running = true;

В коде функции main() необходимо определить массив структур SERVICE_TABLE_ENTRY. Элементами этой структуры является имя службы и указатель на ее главную функцию. Для последнего элемента массива оба этих поля задаются как NULL.

Эту структуру нужно передать как параметр в функцию StartServiceCtrLDispatcher(). После этого будет выполняться код главной функции службы.

void maino {

SERVICE_TABLE_ENTRY disp_table[] =

{{"mysvc".svc_main}.{NULL.NULL}:

StartServiceCtrLDispatcher(disp_table); }

Главная функция службы

Главную функцию службы вызывают во время запуска службы (в результате выполнения StartServiceCtrLDispatcher()) и выполняют к ее остановке. ее код реализует основную функциональность службы (ожидает соединений от клиентов, выполняет запросы и тому подобное). Определение этой функции имеет такой вид:

void WINAPI svc_main(DWORD argc. LPTSTR argv[]){

// код основной функции службы

}

В этой функции нужно выполнить ряд шагов. В первую очередь задаются некоторые параметры службы установлением полей глобальной структуры SERVICE_STATUS. К ним принадлежат:

dwServiceType - тип службы (SERVICE_WIN32_OWN_PR0CESS для обычных служб, которые выполняются в отдельном процессе);

dwCurrentState - текущее состояние службы (в этот момент она ожидает начала выполнения, и этот параметр возлагают ровными SERVICE_START_PENDING);

dwControlsAccepted - допустимые управляющие команды, которые входят в функцию-обработчик команд (SERVICE_ACCEPT_STOP значит, что будет обрабатываться только команда Stop).

Заполнение структуры SERVICE_STATUS выполняется так:

status.dwServiceType = SERVICE_WIN32_OWN_PR0CESS:

status.dwCurrentState = SERVICE_START_PENDING:

status.dwControlsAccepted - SERVICE_ACCEPT_STOP;

После этого необходимо зарегистрировать в системе обработчик керуючих команд этой службы с помощью функции Registerservicectrlhandlero, которая принимает имя службы и адрес функции-обработчика, а возвращает глобальный дескриптор статуса службы.

sth = RegisterServiceCtrLHandler("mysvc",svc_ctrlhandler);

После выполнения этого вызова служба будет иметь возможность реагировать на керуючи команды (например, на команду остановки службы).

На этом подготовительный этап завершают. Теперь можно инициализировать службу (создать сетевые соединения, подготовить внутренние структуры данных и тому подобное). После этого службу переводят в состояние выполнения, для чего задают новое значение поля dwCurrentState для структуры SERVICE_STATUS и вызывают функцию SetServiceStatus(), первым параметром которой является глобальный дескриптор статуса службы, а вторым - указатель на структуру SERVICE_STATUS.

//... инициализация службы

status.dwCurrentState - Service_running;

SetServiceStatus (sth. Sstatus):

После этого служба может выполнять любые действия, которых от нее будет требовать программист (принимать соединение от клиентов и тому подобное).

while (running) {

//... работа службы

}

В данном случае переменная runni ng асинхронный будет изменяться в обработчики команд управления.



Поделиться:


Последнее изменение этой страницы: 2017-01-19; просмотров: 124; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.224.39.74 (0.009 с.)