Сергей Холодилов
Наша служба и опасна и трудна
И на первый взгляд как будто не видна
Ю. Энтин
В статье описаны некоторые детали, относящиеся к программированию служб Windows NT/2000/XP. Она не претендует на полноту или уникальность. Кое-что не охвачено, многое (хотя и не всё) из охваченного вы сможете найти в MSDN или другой литературе. Если вы написали свою первую службу и хотите двигаться дальше, эта статья вам поможет.
Для понимания написанного ниже вы должны быть знакомы со службами. Глубоких знаний не потребуется, достаточно представлять себе архитектуру службы (с точки зрения программиста) и помнить примерное предназначение нескольких API-функций.
Большая часть содержащихся в статье утверждений описывает реакцию Windows на какие-то действия со стороны службы. Полноценная проверка таких утверждений не представляется возможной. Тем более что некоторые из них не документированы.
Я поступил так:
В Windows 2000 Server SP1 я постарался проверить всё. В других версиях только кое-что. Возможно, некоторые полученные факты я истолковал неверно. Но пока что ошибок я не нашёл.
Если утверждение есть в MSDN и/или другом источнике, я проверял его два-три раза, если всё сходилось, считал его верным.
Если утверждение противоречит тому, что написано в MSDN и/или других источниках, продолжительность тестирования зависела от его важности (с моей точки зрения). В этом случае в статье указаны и мои результаты, и информация из MSDN или других источников. Если я считаю утверждение важным, кроме этого указано, какие моменты могли быть упущены во время тестирования. Эта версия статьи не содержит важных спорных утверждений.
Если утверждение не встретилось мне ни в одном источнике, я поступал аналогично предыдущему пункту.
Общие особенности служб
В этой части статьи разобраны вопросы, имеющие непосредственное отношение к любой службе. Разделение на «непосредственные» и «косвенные» условно и субъективно. Принцип, которого я придерживался, таков: если проблема/возможность свойственна службам из-за особенностей их архитектуры, она описана в этой части. Иначе – в следующей.
Установка/удаление
Работа с любой программой начинается с установки и заканчивается удалением. Службы – не исключение. Отличие состоит в том, что при установке службу необходимо зарегистрировать. Можно, конечно, возложить эту задачу на инсталлятор, но, по-моему, правильней и проще писать службы, умеющие устанавливаться/удаляться в полуавтоматическом режиме.
ПРИМЕЧАНИЕ На всякий случай: некоторые умные люди, которые знают, как правильно писать инсталляторы, считают, что в этом вопросе я заблуждаюсь. |
Например, так:
int _tmain(int argc, TCHAR* argv[]) { // Если в командной строке что-то есть - // предположительно, запускает пользователь. if (argc == 2) { // lstricmp - сравнение без учёта регистра. if (lstrcmpi(argv[1], TEXT("/install"))==0) { CmdLine::Install(); } else if (lstrcmpi(argv[1], TEXT("/uninstall"))==0) { CmdLine::Uninstall(); } else { CmdLine::DisplayHelp(); } return 0; } ... | ||
ПРИМЕЧАНИЕ TEXT() и _tmain – для поддержки Unicode (а можно сказать «для поддержки ANSI»). Подробнее в разделе «Unicode». CmdLine – пространство имён. Я их нежно люблю и часто использую. Вообще-то, то, что в командной строке «что-то есть» ничего не доказывает, см. «Мелочи». | ||
Функции, выполняющие собственно установку/удаление, выглядят примерно так:
void CmdLine::Install() { открываем SCM (OpenSCManager) создаём службу (CreateService) закрываем всё, что открыли } void CmdLine::Uninstall() { открываем SCM (OpenSCManager) открываемслужбу (OpenService) удаляемслужбу (DeleteService) закрываем всё, что открыли } |
Отсчёт пошёл…
На некоторых этапах выполнения служба должна выполнить определённые действия за определённый срок. В MSDN с разной степенью конкретности перечислены пять требований. В книге Джеффри Рихтера и Джейсона Кларка «Программирование серверных приложений в Windows 2000» приведено шестое. Ниже перечислены сами требования и мои комментарии к ним.
Служба должна вызвать StartServiceCtrlDispatcher не позже, чем через 30 секунд после начала работы, иначе выполнение службы завершится. Практика подтвердила. Кроме того, в раздел Event Log’а System будет добавлена запись об ошибке (источник – «Service Control Manager»). Если служба запускается вручную из программы Services, пользователь получит сообщение (MessageBox).
Функция ServiceMain должна вызвать RegisterServiceCtrlHandler[Ex] немедленно. Что будет в противном случае – не указано. Несоблюдение этого правила – один из случаев «нарушений во время инициализации» (термин мой), описанных ниже в этом же разделе.
Функция ServiceMain должна вызвать SetServiceStatus первый раз «почти сразу» после RegisterServiceCtrlHandler[Ex], после чего служба должна продолжать вызывать её до тех пор, пока ини
Наверняка у вас есть товары или услуги, продажа которых приносит вам максимальную прибыль. Для быстрого старта в сети вам необходимо создание посадочной страницы (одностраничного сайта), на которой будет размещена информация о маржинальных товарах/услугах интернет магазина. За 8 лет опыта разработки конверсионных страниц мы выработали оптимальную структуру, которая позволит привлекать через landing page больше продаж. На такую структуру «одевается» ваш контент — фирменный стиль, тексты, фотографии, уникальные торговые предложения, после чего страница выходит в свет. Разработка лендинга и запуск в сети — до 7 рабочих дней. Стоит отметить, что в разработку самой посадочной страницы входит и написание копирайтером продающих текстов для вашего бизнеса, чтобы каждый посетитель страницы захотел совершить покупку именно у вас. Результат: качественно разработаная продающая посадочная страница, которая готова приносить вам новых клиентов.