Возможны ситуации, в которых служба и приложения разделяют объект ядра. Например, служба может использовать именованный мьютекс для защиты разделяемой области памяти, используемой для обмена данными с приложениями. Более того, в нашем примере также будет применяться разделяемый объект ядра, которым в данном случае является отображение файла.
Существует одна трудность, связанная с тем, что контекст безопасности приложений отличается от контекста безопасности служб, выполняющихся от имени системной учетной записи. Даже если защита не требуется, было бы нелогично создавать и (или) открывать разделяемые объекты ядра с указателем атрибутов безопасности, установленным в NULL (см. глава 15). Вместо этого необходим, по крайней мере, нулевой список разграничительного контроля доступа (см. главу 15), то есть приложения и служба должны использовать ненулевую структуру атрибутов защиты. В общем случае вы захотите защитить объекты, и этот вопрос также будет рассмотрен в главе 15.
Следует обратить ваше внимание также на то, что если служба выполняется от имени системной учетной записи, то могут возникать трудности с доступом службы к таким ресурсам, как разделяемые файлы, находящиеся на других машинах.
Регистрация событий
Службы часто выполняются, внешне ничем себя не проявляя, без диалогового взаимодействия с пользователем. Некоторые службы создают консоль, окно сообщений[25]или окно для взаимодействия с пользователем, но лучше всего записывать информацию о событиях в файл регистрации событий или использовать соответствующие функциональные возможности, предоставляемые Windows. Такая информация сохраняется в реестре, и ее можно просматривать с помощью специальной программы просмотра событий, предоставляемой группой инструментов Administrative Tools, пиктограмма которой находится в панели управления.
В доступных на Web-сайте книги программах ServiceSK.c и SimpleService.c показано, как организовать регистрацию заслуживающих внимания событий и ошибок в регистрационном файле, а в комментариях к текстам упомянутых программ рассказано о том, как используется регистрация событий. Для этого имеются три функции, описанные в оперативной справочной документации.
1. RegisterEventSource — позволяет получить дескриптор регистрационного файла.
2. ReportEvent — используется для внесения записи в регистрационный файл.
3. DeregisterEventSource — закрывает дескриптор регистрационного файла.
Замечания по отладке службы
Предполагается, что служба будет выполняться непрерывно, поэтому она должна быть надежной и по возможности лишенной каких бы то ни было дефектов. Несмотря на возможность подключения службы к отладчику и использования журнала регистрации событий для отслеживания операций, выполняемых службой, эти методы являются наиболее подходящими в условиях, когда служба уже развернута.
Однако на стадии первоначальной разработки и отладки службы часто гораздо легче воспользоваться преимуществами оболочки службы, представленной в программе 13.2.
• Разработайте сначала предварительную версию службы в виде отдельной программы. В таком ключе, например, была разработана программа serverSK.
• Используйте в программе средства регистрации событий или предусмотрите регистрационный файл.
• Когда вы придете к заключению, что программа готова к развертыванию в виде службы, переименуйте основную точку входа и свяжите ее с кодом оболочки службы, представленным программой 13.2 (он находится на Web-сайте книги вместе с двумя программами: SimpleService.c и serviceSK.c).
• Весьма важную роль играет дальнейшее тестирование службы для обнаружения дополнительных логических ошибок и проблем с обеспечением безопасности. Службы могут выполняться от имени системной учетной записи, но не иметь доступа к пользовательским объектам, и обнаружения проблем подобного рода предварительная версия службы не гарантирует.
• Если служба нуждается в интенсивной поддержке, извлеките ее код из оболочки и превратите его вновь в отдельную программу или консольное приложение, используя для этого GUI или текстовый интерфейс. Можно поступить и по-другому, предусмотрев для функции ServiceMain дополнительный аргумент командной строки, используемый в качестве флага отладки или трассировки.
Резюме
Службы Windows предоставляют стандартные возможности подключения пользовательских служб к системе Windows. Используя методы, обсуждавшиеся в этой главе, любую независимую программу можно превратить в службу.
Для создания служб, а также управления ими и контроля их функционирования можно воспользоваться средствами Administrative Tools (Администрирование) или представленной в этой главе программой ServiceShell. Управление развернутыми службами и их мониторинг осуществляются через SCM, и информация обо всех служб заносится в реестр.
В следующих главах
В главе 14 описывается асинхронный ввод/вывод, который предоставляет два метода, позволяющих выполнять множественные операции ввода/вывода параллельно с другими видами обработки. При этом использование нескольких потоков не является обязательным и требуется всего лишь один пользовательский поток.
В большинстве случаев программировать многопоточное выполнение проще, чем асинхронный ввод/вывод, и производительность в первом случае, как правило, выше. В то же время, без асинхронного ввода/вывода не обойтись, работая с портами завершения ввода/вывода, которые оказываются чрезвычайно полезными при построении масштабируемых серверов, способных взаимодействовать с большим количеством клиентов.
В главе 14 также рассматриваются таймеры ожидания.
Эта тема подробно обсуждается в [21]. Драйверы устройств и их взаимодействие со службами в настоящей главе не рассматривались; соответствующая информация содержится, например, в [24].
Упражнения
13.1. Расширьте возможности службы serviceSK таким образом, чтобы она могла воспринимать команды приостановки.
13.2. При опросе состояния службы оболочка ServiceShell просто выводит соответствующие числовые данные. Расширьте возможности службы, обеспечив вывод информации о состоянии службы в текстовой форме.
13.3. Преобразуйте сервер serverNP (программа 11.3) в службу.
13.4. Видоизмените службу serviceSK, введя в нее средства регистрации событий.
ГЛАВА 14