Студенческий сайт КФУ - ex ТНУ » Учебный раздел » Учебные файлы »Информатика

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

Тип: реферат
Категория: Информатика
Скачать
Купить
Программирование служб: подробностиСергей Холодилов Наша служба и опасна и труднаИ на первый взгляд как будто не виднаЮ. ЭнтинВ статье описаны некоторые детали, относящиеся к программированию служб Windows NT/2000/XP. Она не претендует на полноту или уникальность. Кое-что не охвачено, многое (хотя и не всё) из охваченного вы сможете найти в MSDN или другой литературе. Если вы написали свою первую службу и хотите двигаться дальше, эта статья вам поможет. Для понимания написанного ниже вы должны быть знакомы со службами. Глубоких знаний не потребуется, достаточно представлять себе архитектуру службы (с точки зрения программиста) и помнить примерное предназначение нескольких API-функций. Большая часть содержащихся в статье утверждений описывает реакцию Windows на какие-то действия со стороны службы. Полноценная проверка таких утверждений не представляется возможной. Тем более что некоторые из них не документированы. Я поступил так:В Windows 2000 Server SP1 я постарался проверить всё. В других версиях только кое-что. Возможно, некоторые полученные факты я истолковал неверно. Но пока что ошибок я не нашёл. Если утверждение есть в MSDN и/или другом источнике, я проверял его два-три раза, если всё сходилось, считал его верным. Если утверждение противоречит тому, что написано в MSDN и/или других источниках, продолжительность тестирования зависела от его важности (с моей точки зрения). В этом случае в статье указаны и мои результаты, и информация из MSDN или других источников. Если я считаю утверждение важным, кроме этого указано, какие моменты могли быть упущены во время тестирования. Эта версия статьи не содержит важных спорных утверждений. Если утверждение не встретилось мне ни в одном источнике, я поступал аналогично предыдущему пункту. Общие особенности службВ этой части статьи разобраны вопросы, имеющие непосредственное отношение к любой службе. Разделение на «непосредственные» и «косвенные» условно и субъективно. Принцип, которого я придерживался, таков: если проблема/возможность свойственна службам из-за особенностей их архитектуры, она описана в этой части. Иначе – в следующей.Установка/удалениеРабота с любой программой начинается с установки и заканчивается удалением. Службы – не исключение. Отличие состоит в том, что при установке службу необходимо зарегистрировать. Можно, конечно, возложить эту задачу на инсталлятор, но, по-моему, правильней и проще писать службы, умеющие устанавливаться/удаляться в полуавтоматическом режиме.Например, так:Функции, выполняющие собственно установку/удаление, выглядят примерно так:Отсчёт пошёл…На некоторых этапах выполнения служба должна выполнить определённые действия за определённый срок. В MSDN с разной степенью конкретности перечислены пять требований. В книге Джеффри Рихтера и Джейсона Кларка «Программирование серверных приложений в Windows 2000» приведено шестое. Ниже перечислены сами требования и мои комментарии к ним. Служба должна вызвать StartServiceCtrlDispatcher не позже, чем через 30 секунд после начала работы, иначе выполнение службы завершится. Практика подтвердила. Кроме того, в раздел Event Log’а System будет добавлена запись об ошибке (источник – «Service Control Manager»). Если служба запускается вручную из программы Services, пользователь получит сообщение (MessageBox). Функция ServiceMain должна вызвать RegisterServiceCtrlHandler[Ex] немедленно. Что будет в противном случае – не указано. Несоблюдение этого правила – один из случаев «нарушений во время инициализации» (термин мой), описанных ниже в этом же разделе. Функция ServiceMain должна вызвать SetServiceStatus первый раз «почти сразу» после RegisterServiceCtrlHandler[Ex], после чего служба должна продолжать вызывать её до тех пор, пока инициализация не закончится. Неправильное использование SetServiceStatus – второй случай «нарушений во время инициализации». При обработке сообщения служба должна вернуть управление из функции Handler[Ex] в течение 30 секунд, иначе SCM сгенерирует ошибку. Практика подтверждает, запись в Event Log добавляется. Но никаких репрессивных действий по отношению к службе я не дождался. При получении сообщения SERVICE_CONTROL_SHUTDOWN служба должна закончить работу за время, не превышающее число миллисекунд, указанное в параметре WaitToKillServiceTimeout ключа HKLM\System\CurrentControlSet\Control, иначе будет завершена принудительно. Практика подтвердила. После завершения работы в качестве службы (то есть после посылки службой уведомления об этом) процессу даётся 20 секунд на очистку/сохранение/ещё что-то, после этого процесс завершается. Подробнее в разделе «Корректное завершение». Если ваша служба быстро инициализируется и мгновенно обрабатывает сообщения, в результате чего автоматически удовлетворяет всем пунктам, вам повезло. Если нет, можно использовать несколько потоков. Например, так:Дополнительный поток выполняет необходимую инициализацию, а основной поток вызывает StartServiceCtrlDispatcher. Я не смог придумать, зачем делать что-либо до вызова RegisterServiceCtrlHandler[Ex], но если надо, можно сделать так же, как в (1). Один из потоков посылает уведомления о продвижении процесса, второй выполняет инициализацию. Функция первого потока может быть такой: Уведомления посылаются с помощью функции SetServiceStatus. sStatus – глобальная переменная типа SERVICE_STATUS, описывающая состояние службы, в dwState передаётся состояние, о котором необходимо сообщать, eSendPending – событие, установка которого означает окончание работы этого потока.Забавно, что при таком подходе для служб, запускаемых вручную, видимый результат не меняется (см. ниже о нарушениях во время инициализации).Идея в том, что, если обработка сообщения может затянуться, функция Handler[Ex] инициирует её и завершается, не дожидаясь окончания. Если рабочий поток службы в цикле ожидает каких-то событий, обработку может выполнить он, Handler[Ex] должна только проинформировать его о приходе сообщения, если рабочий поток постоянно занят, можно породить ещё один поток. При подобной реализации необходимо учесть, что следующее сообщение может прийти в течение обработки предыдущего, то есть до того, как служба пошлёт уведомление об окончании обработки. С помощью Services этого не сделать, но пользователь может использовать утилиту Net.exe (синтаксис запуска: net команда имя_службы) или написать свою.Ограничения, накладываемые требованиями (5) и (6) обойти не удаётся. Но, в отличие от (5), в (6) момент посылки уведомления о завершении регулируете вы. Поэтому можно выполнять всю необходимую очистку/сохранение/ещё что-то заранее.Теперь о «нарушениях в процессе инициализации». Варианты нарушений:Задержка перед вызовом RegisterServiceCtrlHandler[Ex]. Задержка перед первым вызовом SetServiceStatus. Слишком большие паузы между вызовами SetServiceStatus. Не меняется поле dwCheckPoint структуры, передаваемой SetServiceStatus. Во всех перечисленных случаях реакция системы будет одинаковой. А именно:
Другие файлы:

Программирование на Visual C++ .NET
В книге рассматриваются такие современные технологии, как многозадачное программирование, программирование сокетов, Web-программирование (в т.ч. и со...

Язык программирования C++
Почему C++. Возникновение и эволюция языка C++. Сравнение языков С++ и С. Эффективность и структура. Процедурное программирование. Модульное программи...

Программирование web-сервисов для .NET
Описание: Книга представляет собой практическое руководство для опытных разработчиков, знакомых с технологией ASP .NET и языком C#. Описано создание и...

Линейное и нелинейное программирование
Общая формулировка задания на курсовой проект. Линейное программирование. Задача целочисленного линейного программирования, с булевскими переменными....

Историческое происхождения служб документационного обеспечения
История развития служб документации и секретарских служб России. Приказное, коллежское, исполнительное делопроизводство. Становление и развитие работы...