Чтение онлайн

на главную - закладки

Жанры

Программирование на Visual C++. Архив рассылки

Jenter Алекс

Шрифт:

 CloseDesktop(hdeskUser);

 CloseWindowStation(hwinstaUser);

 return result;

}

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

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

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

Функция main

Вот

как выглядит код функции main:

void main {

 SERVICE_TABLE_ENTRY steTable[] = {

{SERVICENAME, ServiceMain}, {NULL, NULL}

 };

 // Устанавливаем соединение с SCM. Внутри этой функции

 // происходит прием и диспетчеризация запросов.

 StartServiceCtrlDispatcher(steTable);

}

Функция ServiceMain

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

Для преодоления этой проблемы все операции по взаимодействию с SCM следует выполнять в отдельном потоке, не зависящем от действий, происходящих на этапе инициализации.

Алгоритм корректного запуска службы, использующий вспомогательный поток:

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 секунду

 // событие hSendStartPending не перешло

 // в сигнальное состояние (инициализация службы не

 // закончилась), посылаем очередное уведомление,

 // установив максимальный интервал времени

 // в 2 секунды, для того, чтобы был запас времени до

 // следующего уведомления.

 while (true) {

SetServiceStatus(hSS, &sStatus);

sStatus.dwCheckPoint++;

if (WaitForSingleObject(hSendStartPending, 1000) != WAIT_TIMEOUT) break;

 }

 sStatus.dwCheckPoint = 0;

 return 0;

}

// Функция, инициализирующая службу. Чтение данных,

// распределение памяти и т.п.

Поделиться:
Популярные книги

Газлайтер. Том 18

Володин Григорий Григорьевич
18. История Телепата
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Газлайтер. Том 18

Секретарь лорда Демона

Лунёва Мария
Фантастика:
попаданцы
фэнтези
5.00
рейтинг книги
Секретарь лорда Демона

Жатва душ. Остров мертвых

Сугралинов Данияр
Фантастика:
боевая фантастика
рпг
5.20
рейтинг книги
Жатва душ. Остров мертвых

Кодекс Крови. Книга ХII

Борзых М.
12. РОС: Кодекс Крови
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Кодекс Крови. Книга ХII

Протокол "Наследник"

Лисина Александра
1. Гибрид
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Протокол Наследник

Найденыш

Шмаков Алексей Семенович
2. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
5.00
рейтинг книги
Найденыш

Служанка. Второй шанс для дракона

Шёпот Светлана
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Служанка. Второй шанс для дракона

Кодекс Охотника. Книга XXI

Винокуров Юрий
21. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XXI

Флеш Рояль

Тоцка Тала
Детективы:
триллеры
7.11
рейтинг книги
Флеш Рояль

Имперский Курьер. Том 2

Бо Вова
2. Запечатанный мир
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Имперский Курьер. Том 2

Громовая поступь. Трилогия

Мазуров Дмитрий
Громовая поступь
Фантастика:
фэнтези
рпг
4.50
рейтинг книги
Громовая поступь. Трилогия

Наследница долины Рейн

Арниева Юлия
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Наследница долины Рейн

Демон

Парсиев Дмитрий
2. История одного эволюционера
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Демон

Ищу жену с прицепом

Рам Янка
2. Спасатели
Любовные романы:
современные любовные романы
6.25
рейтинг книги
Ищу жену с прицепом