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

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

Жанры

Программирование на 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;

}

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

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

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

Часовая башня

Щерба Наталья Васильевна
3. Часодеи
Фантастика:
фэнтези
9.43
рейтинг книги
Часовая башня

Попаданка в Измену или замуж за дракона

Жарова Анита
Любовные романы:
любовно-фантастические романы
6.25
рейтинг книги
Попаданка в Измену или замуж за дракона

На границе империй. Том 9. Часть 3

INDIGO
16. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 3

Жена на пробу, или Хозяйка проклятого замка

Васина Илана
Фантастика:
попаданцы
фэнтези
5.00
рейтинг книги
Жена на пробу, или Хозяйка проклятого замка

Ваше Сиятельство

Моури Эрли
1. Ваше Сиятельство
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Ваше Сиятельство

Восход. Солнцев. Книга I

Скабер Артемий
1. Голос Бога
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Восход. Солнцев. Книга I

Инвестиго, из медика в маги

Рэд Илья
1. Инвестиго
Фантастика:
фэнтези
городское фэнтези
попаданцы
5.00
рейтинг книги
Инвестиго, из медика в маги

Надуй щеки!

Вишневский Сергей Викторович
1. Чеболь за партой
Фантастика:
попаданцы
дорама
5.00
рейтинг книги
Надуй щеки!

Случайная свадьба (+ Бонус)

Тоцка Тала
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Случайная свадьба (+ Бонус)

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

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

Мастер Разума III

Кронос Александр
3. Мастер Разума
Фантастика:
героическая фантастика
попаданцы
аниме
5.25
рейтинг книги
Мастер Разума III

Наследник 2

Шимохин Дмитрий
2. Старицкий
Фантастика:
попаданцы
альтернативная история
фэнтези
5.75
рейтинг книги
Наследник 2

Неучтенный. Дилогия

Муравьёв Константин Николаевич
Неучтенный
Фантастика:
боевая фантастика
попаданцы
7.98
рейтинг книги
Неучтенный. Дилогия

Светлая тьма. Советник

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