Вход/Регистрация
Программирование на Visual C++. Архив рассылки
вернуться

Jenter Алекс

Шрифт:

Следующий фрагмент кода иллюстрирует такую возможность.

// Функция, аналог MessageBox Win32 API

int ServerMessageBox(RPC_BINDING_HANDLE h, LPSTR lpszText, LPSTR lpszTitle, UINT fuStyle) {

 DWORD dwThreadId;

 HWINSTA hwinstaSave;

 HDESK hdeskSave;

 HWINSTA hwinstaUser;

 HDESK hdeskUser;

 int result;

 // Запоминаем текущие объекты "Window station" и "Desktop".

 GetDesktopWindow;

 hwinstaSave = GetProcessWindowStation;

 dwThreadId = GetCurrentThreadId;

 hdeskSave = GetThreadDesktop(dwThreadId);

 // Меняем контекст безопасности на тот,

 // который есть у вызавшего клиента RPC

 // и получаем доступ к пользовательским

 // объектам "Window station" и "Desktop".

 RpcImpersonateClient(h);

 hwinstaUser = OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED);

 if (hwinstaUser == NULL) {

RpcRevertToSelf;

return 0;

 }

 SetProcessWindowStation(hwinstaUser);

 hdeskUser = OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED);

 RpcRevertToSelf;

 if (hdeskUser == NULL) {

SetProcessWindowStation(hwinstaSave);

CloseWindowStation(hwinstaUser);

return 0;

 }

 SetThreadDesktop(hdeskUser);

 // Выводим обычное текстовое окно.

 result = MessageBox(NULL, lpszText, lpszTitle, fuStyle);

 // Восстанавливаем сохраненные объекты

 // "Window station" и "Desktop".

 SetThreadDesktop(hdeskSave);

 SetProcessWindowStation(hwinstaSave);

 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;

  • Читать дальше
  • 1
  • ...
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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