Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lection 6.doc
Скачиваний:
79
Добавлен:
13.04.2015
Размер:
198.66 Кб
Скачать

6.2. Соглашения по работе с реестром

При сохранении параметров приложения в реестре очень важно определить, кому эта информация предназначена: компьютеру (т. е. всем пользова­телям) или одному пользователю. Иначе говоря, должна ли конфигурация не­которого компонента приложения быть одинаковой для всех пользова­телей или каждый пользователь будет настраивать ее по-своему? Обычно информация, сохраняемая в реестре при установке ПО, применя­ется для всех пользователей. Этот процесс очень похож на установку в систе­му нового устройства. И наоборот: изменения, внесенные пользователем в кон­фигурацию приложения во время его выполнения, обычно сохраняются для конкретного пользователя.

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

HKEY_LOCAL_MACHINE Software

Company Name

Your Product Name

Your Product Version (optional)

Key1

Valuel

Value2

Key2

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

Параметры реестра, специфичные для пользователя. Подразделы раздела HKEY_USERS содержат сведения о пользовательских параметрах. Система автоматически устанавливает соответствие между HKEY_CURRENT_USER и подразделом, описывающим текущего, т. е. ассоциированного с текущим процессом, пользователя. Если поток заимствует права другого пользователя, все обращения этого потока к HKEY_CURRENT_USER будут относиться к этому пользователю. Если приложение будет обращаться к специфичной для пользователя информации реестра, оно должно следовать соглашению, похожему на применяемое в случае для раздела HKEY_LOCAL_MACHINE:

HKEY_CURRENT_USER

Software

Your Company Name

Your Product Name

Your Product Version (optional)

Key1

Valuel

Value2

Key2

Конечно, к этой иерархии можно обращаться и прямо через корневой раздел HKEY_USERS, но делать этого не рекомендуется. Если все-таки необходимо выполнить такую операцию, то используйте функцию RegOpenCurrentUser.

6.3. Работа с реестром c использованием функций Windows api

Дескриптор ключа (подраздела) (key handle) хранится в переменной типа HKEY. Чтобы по­лучить дескриптор ключа HKEY, необходимо использовать функции RegOpenKeyEx или RegCreateKeyEx. Первый аргумент этих функций имеет тип HKEY. При вызове любой из этих функций в качестве первого аргумента можно указать константу, например имя одного из корневых ключей реестра (на­пример, HKEY_CLASSES_ROOT). Windows позволяет воспользоваться несколькими константами типа HKEY, которые по умолчанию являются открытыми. Этими константами являются:

HKEY_CLASSES_ROOT

HKEY_CURRENT_USER

HKEY_LOCAL_MACHINE

HKEY_USERS

HKEY_CURRENT_CONFIG

HKEY_DYN_DATA

Эти константы соответствуют корневым ключам реестра. Для работы с реестром из программы могут быть использованы функции API Windows (табл. 6.3), а в системах программирования как С++ Builder и Delphi для работы с реестром предусмотрен специальный класс TRegistry, который предоставляет все необходимые функции для работы с реестром.

Таблица 6.3 - Некоторые (часто используемые) функции API для работы с реестром

Функция

Описание

RegCloseKey

Закрыть открытый ключ реестра

RegConnectRegistry

Подключиться к удаленному реестру

RegCreateKeyEx

Создать новый подключ

RegDeleteKey

Удалить ключ

RegDeleteValue

Удалить значение

RegEnumKeyEx

Перейти к следующему подключу (каждый раз возвращает новый ключ)

RegEnumValue

Перейти к следующему значению (каждый раз возвращает новое значение)

RegFlushKey

Внести значения ключа в реестр (чтобы убедиться в том, что все изменения сохранены на диске)

RegLoadKey

Загрузить ключ из специального файла (см. также RegSaveKey)

RegOpenKeyEx

Открыть ключ

RegQueryInfoKey

Запросить информацию о ключе

RegQueryValueEx

Прочитать значение

RegReplaceKey

Заменить ключ после перезапуска системы

RegSaveKey

Записать ключ в файл

RegSetKeySecurity

Установить разрешения на доступ к ключу

RegSetValueEx

Установить значение

RegUnloadKey

Выгрузить набор значений

Если требуется получить пару имя/значение текущего ключа, следует восполь­зоваться функцией RegQueryValueEx, Этот вызов принимает имя и возвращает соответствующее этому имени значение ключа. Если не известно, какие значения содержит данный ключ, то необходимо использо­вать функцию RegEnumValue, при помощи которого можно последовательно переби­рать пары имя/значение, хранящиеся в рамках открытого вами ключа.

При использовании вызова RegEnumValue следует учитывать, что если ключ обладает лишь одним значением по умолчанию, функция вернет это значе­ние. Однако, если помимо значения по умолчанию ключ содержит в себе другие пары имя/значение, функция RegEnumValue последовательно вернет вам эти пары, однако при этом значение по умолчанию будет пропущено. Каждый ключ реестра может обладать значением по умолчанию (имя этого значения — пустая строка), а также набо­ром других значений, каждое из которых идентифицируется при помощи сим­вольного имени.

Следующая функция (пример 6.1) является примером работы с реестром и выполняет перечисление содержимого ключа реестра HKEY_CURRENT_USER\Software. Работа с реесторм реализована с использованием исключительно API функций, но в целом данную функцию можно будет применить только в приложениях ATL или MFC, в связи с использованием класса CString.

Пример 6.1. Функция перечисления содержимого ключа реестра HKEY_CURRENT_USER\Software

void RegReadSample (CString &strResult)

{

TCHAR szBuff[MAX_PATH];

DWORD dwBSize = MAX_PATH, dwIndex = 0;

HKEY hKey = 0;

LONG lResult = 0;

FILETIME ft;

lResult = ::RegOpenKeyEx(HKEY_CURRENT_USER, _T("software"), 0, KEY_ENUMERATE_SUB_KEYS, &hKey);

if(lResult==ERROR_SUCCESS)

{

while(lResult==ERROR_SUCCESS)

{

lResult=::RegEnumKeyEx(hKey,dwIndex,szBuff,&dwBSize,0,0,0,&ft);

if(lResult==ERROR_SUCCESS)

{

dwIndex++;dwBSize = MAX_PATH;

strResult += (CString(szBuff)+_T("\r\n"));

}

}

}

UpdateData(0);

}

При разработке приложения для реализации его интерфейса использованы классы MFC. В данном примере использованы следующие функции для работы с реестром: RegOpenKeyEx, RegEnumKeyEx.

Очень важно при работе с реестром помнить об особенности функции RegDeleteKey. При вызове этой функции необходимо обязательно проверять параметр, передаваемый в эту функцию, на наличие в нем информации. Этот параметр не должен быть пустым, в противном случае операционная система может быть очень серьезно повреждена, в особенности, если это Windows 98.

В случае успешного выполнения этих функций, возвращается значение ERROR_SUCCESS. При вызове функции RegOpenKeyEx использован параметр KEY_ENUMERATE_SUB_KEYS, который указывает тип маски доступа к ключам реестра. Указанное значение не единственное. Все возможные значения этого параметра приведены в таблице 6.4.

Таблица 6.4. Значения типов доступа к ключам реестра

Значение параметра

Описание

KEY_ALL_ACCESS

Комбинация значений всех масок безопасности для доступа: KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY, KEY_CREATE_SUB_KEY, KEY_CREATE_LINK, и KEY_SET_VALUE

KEY_CREATE_LINK

Разрешение создания символической ссылки

KEY_CREATE_SUB_KEY

Разрешение создания подключа

KEY_ENUMERATE_SUB_KEYS

Разрешение перечисления (перебора) подключей

KEY_EXECUTE

Разрешение для чтения

KEY_NOTIFY

Разрешение для уведомления об изменении

KEY_QUERY_VALUE

Разрешение для запроса значения подключа

KEY_READ

Комбинация масок безопасности: KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS и KEY_NOTIFY

KEY_SET_VALUE

Разрешение установки значения подключа

KEY_WRITE

Комбинация масок доступа KEY_SET_VALUE и KEY_CREATE_SUB_KEY

При работе с реестром необходимо помнить, что доступ к реестру в целом и к его ключам в частности регулируется правами пользователя, профиль которого активен в данный момент на компьютере. Это касается операционных систем семейства Windows NT, а в ОС Windows 98/Me эти ограничения не действуют. Учет прав пользователя крайне важен, поскольку программы, работающие с реестром могут не иметь доступа к тем или иным ключам в зависимости от прав пользователя. Полный доступ к реестру имеют программы, запускаемые в режиме администратора или пользователей с правами администратора.

6.4. Работа с реестром при помощи класса TRegistry (Delphi и C++ Builder)

Рассмотрим некоторые функции, которые предоставляются классом TRegistry.

Функция CreateKey предназначена для создания нового ключа в реестре. Входным параметром функции является имя ключа, который нужно создавать. Ключ может быть абсолютным или относительным параметром. Абсолютный ключ начинается со знака “\” и подключа главного (корневого) ключа. Относительный ключ - это подключ текущего ключа. После создания ключа он не имеет никакого значения и его надо установить при помощи специальных функций, таких как WriteBinaryData, WriteBool, WriteCurrency, WriteDate, WriteDateTime, WriteExpandString, WriteFloat, WriteInteger, WriteString, WriteTime.

Эта функция возвращает True, если создание прошло успешно. Попытка создания ключа, который уже существует и не приводит ни к какому результату.

Функция CreateKey создает ключи с уровнем доступа “для всех”. Если необходимо создавать ключи со специальным уровнем доступа, то необходимо напрямую вызывать функции Windows API.

Функция DeleteKey предназначена для удаления существующего ключа в реестре. Она возвращает True, если удаление прошло успешно.

Функция CloseKey используется для закрытия текущего ключа. Перед закрытием будет осуществлена запись текущего ключа. Вызов этой функции без текущего ключа не дает никакого эффекта.

Функция DeleteValue используется для удаления значения из текущего ключа. Параметром, передаваемым в эту функцию, является строка, которая содержит значение, которое надо удалить. Ключ может содержать несколько значений и каждое из этих значений должно иметь уникальное имя. Функция возвращает True, если удаление прошло успешно.

Функции GetDataInfo, GetDataSize, GetDataType, GetKeyInfo, GetKeyNames, GetValueNames предназначены для получения информации.

Функция HasSubKeys определяет, существует ли заданный подключ. Если он существует, то возвращается True.

Функция KeyExists определяет, существует ли заданный ключ реестра с указанным именем. Функция возвращает True если ключ существует.

Функция LoadKey. Эта функция создает подключ в указанном корневом ключе и загружает информацию из файла в созданный ключ. Файл, который загружается в реестр, должен содержать данные о значениях, подключах и значения для этих подключей.

Перед вызовом этой функции значение свойства RootKey объекта TRegistry должно быть установлено в HKEY_USERS, HKEY_LOCAL_MACHINE или в то значение, которое будет возвращено функцией RegistryConnect.

Параметр “имя файла”, передаваемый в функцию, не должен содержать расширение, если программа будет работать с файловой системой FAT. Загружаемый файл необходимо создавать вручную, следуя специальным требованиям, либо при помощи функции SaveKey из объекта TRegistry или RegSaveKey из Windows API.

Функция MoveKey перемещает существующий ключ реестра вместе со всем его содержимым в указанный ключ. Функция имеет два параметра. Первый параметр указывает старый ключ, откуда необходимо перемещать данные, а второй параметр содержит ключ, куда необходимо перемещать данные. Если указанный новый ключ не существует, то он будет создан.

Функция OpenKey. Эта функция открывает указанный ключ. Функция возвращает True, если открытие произошло успешно. Также функция имеет дополнительный параметр, который указывает на необходимость создания ключа в случае, если он не существует.

Функция OpenKeyReadOnly открывает ключ только для чтения. Функция возвращает True, если открытие произошло успешно.

Функции ReadBinaryData, ReadBool, ReadCurrency, ReadDate, ReadDateTime, ReadFloat, ReadInteger, ReadString, ReadTime позволяют прочитать из реестра данные соответствующего типа.

Функция RegistryConnect осуществляет подключение к реестру другого компьютера, подключенного по сети. Передаваемый параметр - это имя удаленного компьютера. Перед вызовом этой функции необходимо установить свойство RootKey объекта TRegistry в значения HKEY_USERS или HKEY_LOCAL_MACHINE. Функция возвращает True, если открытие реестра прошло успешно.

Функция RenameValue изменяет имя значения, ассоциированного с текущим ключом. Функция имеет два парметра: старое и новое имя значения.

Функция ReplaceKey осуществляет замену указанного ключа данными, сохраненными в файле. Функция возвращает True, если замена ключа произошла успешно. Файл должен быть сохранен при помощи функций SaveKey объекта TRegistry или RegSaveKey функции API Windows. Если на компьютере используется файловая система FAT, то имя файла не должно содержать расширение.

Функция SaveKey позволяет сохранить данные и подключи из указанного ключа (подключа) в файл на диске. При вызове этой функции будет использован уровень безопасности KEY_ALL_ACCESS. Если на компьютере используется файловая система FAT, то имя файла не должно содержать расширение. Если функция выполняется успешно, то возвращается True и ключ закрывается.

Функция ValueExists определяет наличие данных для указанного ключа реестра. Эта функция может использоваться для проверки наличия данных перед вызовом других функций записи и модификации реестра.

Функции WriteBinaryData, WriteBool, WriteCurrency, WriteDate, WriteDateTime, WriteExpandString, WriteFloat, WriteInteger, WriteString, WriteTime позволяют записывать данные в реестр соответствующего типа.

Функции API Windows для работы с реестром полностью аналогичны. Ниже приведен фрагмент программы, который демонстрирует использование функций класса TRegistry.

Пример 6.2. Получение списка программного обеспечения, установленного на компьютере (с использованием функций API Windows)

//Функции получения списка установленного ПО Используемые типы данных:

type

TInstallAppItem = class(TObject)

public

Apps : TStringList;

AppInfo : TInstallAppInfo;

constructor Create;

destructor Destroy; override;

procedure Collect;

end;

var

UninstallKey : String = 'Software\Microsoft\Windows\CurrentVersion\Uninstall';

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]