Язык скриптов реестра в ATL

Что же такое RGS-файл (ReGistry Script)? ATL поддерживает простой и элегантный язык скриптов для задания, что вставить (удалить) в (из) реестр системы в процессе инсталляции. Этот язык скриптов реестра устраняет необходимость поддерживать REG-файл, чтобы регистрировать СОМ-серверы. По умолчанию, RGS-файл задает ProgID с версией, ProgID без версии и идентификаторы clsid. Информация об интерфейсах сервера и TypeLib вносится программно.

Синтаксис RGS построен по стандартному иерархическому принципу, с идентификацией каждого "узла" парой скобок ({}). Самый верхний узел (в данном случае HKCR) используется для задания улья, который будет модифицироваться скриптом. Синтаксис RGS позволяет заносить информацию в любой улей реестра. Список допустимых значений приводится в табл. 4.2.

Конструкции языка скриптов реестра ATL Таблица 4.2.

Сокращенное обозначение улья Значение
HKCR HKCR HKML HKU HKPD HKDD HKCC HKEY_CLASSES_ROOT HKEY_CURRENT_USER HKEY_LOCAL_MACHINE HKEY_USERS HKEY_PERFORMANCE_DATA HKEY_DYN_DATA HKEY_CURRENT_CONFIG

Подузлы могут иметь модификаторы. Узел CLSID принимает NoRemove, означающий, что любые записи, вносимые в HKCR\CLSID, требуют сохранять все другие подключи нетронутыми. С другой стороны, запись {<GUID>} для класса снабжена модификатором ForceRemove, сообщающим ATL, что необходимо убрать все имеющиеся под этим ключом записи и заменить их на требуемые. И, наконец, хотя это и отсутствует в RGS-файле, узел может получить модификатор Delete, используемый для удаления (без замены) существующего ключа.

Подключ может содержать различные величины. В синтаксисе RGS именованные величины маркируются модификатором val. Синтаксис RGS позволяет вносить строковые (S), численные (D для DWORD) или двоичные (В) величины.И последнее, что нас интересует, — это тэг %module%. Синтаксис RGS позволяет определять метки-заполнители, которые динамически добавляются в скрипт во время процесса регистрации/дерегистрации. %module% — один из таких предопределенных заполнителей, заменяющийся на вызов функции Win32 GetModuleFileName(). Имеется возможность определить и свои собственные метки-заполнители.

Библиотека выполняет довольно большую работу, предоставляя код хранилища компонентов, а также базовой "оснастки" СОМ (фабрика класса, реализация IUnknown, поддержка саморегистрации).

Распределенная COM (DCOM)

СОМ разрабатывалась с учетом обеспечения поддержки распределенных сред, т.е. способности клиента создавать объекты на других машинах и вызывать их методы по сети. Эти планы стали реальностью в 1996 году после выпуска распределенной СОМ (Distributed СОМ — DCOM). DCOM позволяет клиенту создавать и использовать объекты как на удаленных системах, так и на локальной. Более того, клиент может даже не осознавать различия между этими двумя случаями. Подобно тому как клиенты СОМ имеют прозрачный доступ к объектам в динамических библиотеках и локальных процессах, DCOM обеспечивает прозрачный доступ к объектам в удаленных процессах. Фактически самое трудное в достижении подобной прозрачности — это обеспечить взаимодействие объектов, исполняющихся в разных процессах независимо от того, выполняются эти процессы на одной машине или нет. В этом смысле, с точки зрения проектирования, DCOM — довольно незначительное расширение оригинальной СОМ.

Возможность запускать удаленные объекты и вызывать их методы — важное достижение, но требуется большее. В частности, нужен способ контроля за тем, кто имеет право создавать объекты на данной машине, и обеспечение безопасного доступа к этим объектам по сети, которая может быть наполнена потенциальными врагами. С этой целью в основу DCOM положен набор сервисов контроля доступа. Приложения (включая программы, созданные до DCOM) могут использовать DCOM и работать вполне безопасно без добавления какого-либо кода, связанного с защитой. С другой стороны, приложения, знающие о новых средствах DCOM контроля доступа, могут задействовать их явно. Несмотря на отдельные сложные моменты, DCOM вообще проста для понимания. Она добавляет к знакомым основам СОМ всего 3 основных элемента:

· способ создания удаленного объекта;

· протокол вызова методов этого объекта;

· механизмы обеспечения безопасного доступа к нему.

Сеть можно переполнить тестовыми сигналами, особенно если сотни клиентов используют сотни интерфейсов от удаленных объектов, что требует более эффективного технического решения. Поэтому средства DCOM группируют тестовые сигналы от одного клиентского компьютера в один тестовый сигнал. Вместо пересылки всей информации тестового опроса с каждым тестом, средства DCOM группируют в него только изменения, появившиеся после предыдущего опроса. Этот способ эффективнее, чем пересылка одного теста для каждого интерфейса у каждого из объектов.

DCOM и службы NT

Иногда приложение содержит вызов программы, исполняемой на сервере в непрерывном автоматическом режиме. Например, программа ожидает файлы, которые нужно поместить в каталог и каким-то образом обработать (возможно, импортировать в базу данных). Простая программа здесь не годится, поскольку для ее работы требуется, чтобы в компьютерную систему вошел какой-либо пользователь. А службы не имеют такого ограничения.

Службы исполняются независимо от того, вошел кто-либо в систему или нет. Каждая служба входит в систему и выдает себя за определенного пользователя. Обычно при запуске системы службы начинают исполняться автоматически; но можно задать для службы запуск вручную. Служба должна быть зарегистрирована и связана с диспетчером SCM, отвечающим за управление конфигурацией, запуск и остановку служб. Но как служба связывается с диспетчером SCM? Диспетчер SCM (Service Control Manager - диспетчер управления службами) обеспечивает управление службами Windows NT. Не следует путать диспетчер SCM с диспетчером COM SCM, который отвечает за определение местонахождения и создание экземпляров служб СОМ.

Структура службы NT

Все службы Windows NT должны выполнять две стандартные функции, предназначенные для взаимодействия с диспетчером SCM. При запуске службы, как и в обычном исполняемом модуле, вызывается функция main() или WinMain(). Но, в отличие от обычного исполняемого модуля, эта функция вызывает функцию StartServiceCtrlDispatcher() библиотеки API, информирующую диспетчер SCM обо всех службах в исполняемом модуле. Единственный исполняемый модуль может содержать несколько служб. Диспетчер SCM для запуска каждой службы использует функцию ServiceMain(). Когда вызывается функция ServiceMain(), она сама себя запускает (например, начинает исполнение цикла обработки сообщений).

Диспетчер SCM взаимодействует со службой во время ее исполнения, отдает ей команды, например Stop (Стоп) или Pause (Пауза) с помощью функции обработчика (handler function), зарегистрированной диспетчером SCM, использующим API-функцию RegisterServiceCtrlHandler(). Функция ServiceMain() обеспечивает вызов этой API-функции перед запуском службы. После установления этой псевдосвязи между службой и SCM диспетчер SCM может вызывать функцию обработчика, предписывая службе остановиться. Служба останавливает исполнение и возвращает сообщение (например, отправив сообщение WM_QUIT в исполняемый поток).

Наши рекомендации