Цель работы: освоение методики и функций Win32 для работы с реестром. Знакомство с компонентом Registry, его свойствами и методами.
Структура реестра
Реестр — это база данных, которая является частью операционной системы Windows 9x или NT.
Реестр хранит информацию, используемую для инициализации и конфигурирования приложений и управляет доступом к ней. Все технологии на платформе Windows интенсивно используют реестр.
Реестр Windows 9x состоит из файлов user.dat и system.dat, представляющих собой скрытые файлы, находящиеся в каталоге \Windows. ПЕРЕД началом работы с реестром необходимо сохранить копию этих файлов.
Реестр имеет иерархическую структуру и состоит из разделов и пар параметр-значение. Структура реестра напоминает иерархическую структуру каталогов Windows — разделы можно представлять себе в виде папок, а пары параметр-значение — в виде файлов. Редактор реестра RegEdit — основной инструмент пользователя для манипуляции с реестром, предоставляемый Microsoft.
Разделы
Раздел — это узел структуры реестра. Он состоит из подразделов и пар параметр-значение. Имя подраздела должно быть уникальным внутри его родительского раздела. Для отделения имен родительских разделов от дочерних используется символ \
HKEYs
Разделы HKEYs — это средство доступа к разделам реестра самого верхнего уровня. Они определяются в API реестра и являются точкой входа в дерево реестра. В реестре есть ДВА основных раздела — HKEY_LOCAL_MACHINE и HKEY_USERS (которые хранятся соответствен-но в файлах system.dat и user.dat) и четыре дополнительных раздела.
Пары параметр-значение
Пара параметр-значение — компонент реестра, который непосредственно хранит данные. Используя путь к разделу и имя параметра, можно считать значение из пары параметр-значение.
Значение, находящееся в паре, может иметь один из нескольких типов. Три основных типа данных- двойное слово (DWORD), строка (String) и двоичное значение (Binary).
Редактор реестра
Для запуска редактора реестра используется меню Пуск-> Выполнить. В окне имени файла необходимо ввести regedit и нажать ОК. Редактор реестра дает возможность просматривать содержимое реестра, создавать и удалять подразделы и пары параметр-значение, выполнять экспорт-импорт всего реестра или его части.
НИКОГДА НЕ УДАЛЯЙТЕ ПОДРАЗДЕЛЫ и ПАРЫ ПАРАМЕТР_ЗНАЧЕНИЕ, которые ВЫ не создавали!
Редактор реестра поддерживает только три типа данных (перечисленные выше) из 9. Для выполнения операций с данными других типов необходимо использовать функции Win32 API.
Функции Win32 для работы с реестром
- Открытие и закрытие родительского раздела.
Перед началом выполнения любых операций с разделом его необходимо открыть ( как и при работе с любой базой данных). Для открытия раздела используется функция
RegOpenKeyEx
( HKEY_LOCAL_MACHINE, // имя корневого раздела
‘SOFTWARE\Borland’, // имя открываемого подраздела
0, // зарезервированное значение
KEY_ALL_ACCESS, // вид доступа к разделу — полный доступ
hkkey ) // возвращаемое значение — Handle раздела — типа HKEY.
При успешном открытии возвращается ERROR_SUCCESS, т.е. 0. Если подраздел не существует, возвращается 2.
После окончания работы с подразделом его необходимо закрыть, используя функцию
RegCloseKey (hkkey);
- Создание подразделов.
Для создания подраздела в существующем разделе используется функция RegCreateKeyEx, с помощью которой можно открыть существующий раздел, или создать новый подраздел. Пример вызова функции
RegCreateKeyEx
( HKEY_LOCAL_MACHINE, // имя корневого раздела
‘SOFTWARE\myrazd’, // имя создаваемого подраздела
0, // резерв, всегда 0
», // имя класса или типа объекта раздела — пустая строка
REG_OPTION_NON_VOLATILE, // постоянный раздел
KEY_ALL_ACCESS, // вид доступа к разделу
nil, // атрибут безопасности
hkkey, // описатель раздела, тип HKEY
@result ) : integer — код ошибки // Result — типа DWORD.
Параметр result типа DWORD принимает значения REG_CREATED_NEW_KEY или
REG_OPENED_EXISTING_KEY.
- Установка значения параметра.
Функция RegSetValueEx создает в открытом или созданном разделе пару параметр-значение. Пример вызова функции
RegSetValueEx
( описатель созданного или открытого раздела,
имя пары параметр-значение,
0, // резерв — всегда 0
REG_SZ, // тип значения — строка с 0 в конце
Strd, // переменная типа Pchar, которой присвоено необходимое значение
Length (strd) // длина значения
) ;
- Получение значения параметра
Для чтения значения параметра используется функция RegQueryValueEx.
Необходимо описать переменные:
dwType : DWORD — тип возвращаемого значения
buf : Array [1..n] of char -массив для получения значения строкового параметра
len : DWORD — длина буфера
и присвоить переменным значения dwType := REG_SZ;
len:= N;
Вызов функции для чтения значения параметра
Error := RegQueryValueEx (
hkkey, // handle открытого раздела
имя параметра, // имя должно быть записано в апострофах
nil, // зарезервированное значение
@dwType, // адрес типа возвращаемого значения
@buf, // адрес буфера
@len );
if Error = ERROR_SUCCESS then // если нет ошибки — получить значение параметра
for k:=1 to len-1 do str := str + buf [ k ];
- Удаление раздела и его значений — функция RegDeleteKey.
- Получение информации из открытого раздела — RegQueryInfoKey (). Функция возвращает:
- количество подразделов;
- длину самого длинного имени подраздела;
- количество пар;
- длину самого длинного имени параметра;
- длину самого длинного значения;
- Просмотр пар параметр- значение — функция RegEnumValue (). Среди прочего, возвращает информацию о типе значения данной пары.
- Уведомление приложения об изменениях в разделе — RegNotifyChangeKeyValue. Она может сгенерировать событие при изменении имен раздела или создании и удалении раздела (для раздела или подраздела). Пример использования данной функции приведен ниже
procedure TForm1.Button1Click(Sender: TObject);
var
ev : Thandle; err : dword;
hkkey : hkey; result : DWORD;
begin
ev:=CreateEvent(nil,true,false,’name’);
err:= RegCreateKeyEx
( HKEY_LOCAL_MACHINE, //
‘SOFTWARE’, //
0,
»,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
nil,
hkkey,
@result );
RegNotifyChangeKeyValue (hkkey,True,
REG_NOTIFY_CHANGE_NAME,
ev,true);
waitforSingleObject( ev, infinite);
ShowMessage (‘ Реестр изменен ‘);
end;
Использование компонента Registry
Пример1. Приведенный фрагмент по введенному в окне редактирования пути (он может быть пустым) к разделу реестра (расположенного в HKEY_LOCAL_MACHINE\SOFTWARE) дает возможность получить список его подразделов, а для подраздела, имеющего список пар параметр-значение — список имен параметров. Не забудьте добавить registry в uses.
procedure TForm1.Button1Click(Sender: TObject);
var reg : Tregistry; res : boolean; strs : TstringList; i : integer;
begin
ListBox1.Clear; ListBox2.Clear;
reg:=Tregistry.Create; strs:=TstringList.Create;
reg.RootKey:=HKEY_LOCAL_MACHINE;
reg.OpenKey(‘SOFTWARE\’+Edit1.Text,False);
if res then label1.caption:=’ok’;
// получение списка имен ключей (подразделов) раздела, путь которого указан строкой
// SOFTWARE\ и строкой, введенной в окне редактирования Edit1
reg.GetKeyNames(strs);
label2.Caption:=inttostr(strs.count);
for i:=1 to strs.count-1 do listbox1.Items.add(strs.strings[i]);
// получить имена параметров данного раздела
reg.GetValueNames(strs);
label2.Caption:=inttostr(strs.count);
for i:=1 to strs.count do listbox2.Items.add(strs.strings[i-1]);
reg.CloseKey;
end;
Пример 2. Поиск в разделе реестра заданного имени подраздела.
Const
RtK : array[1..6] of HKEY = (HKEY_CLASSES_ROOT, HKEY_CURRENT_USER,
HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CURRENT_CONFIG, HKEY_DYN_DATA);
RKS: array[1..6] of String = (‘HKEY_CLASSES_ROOT’, ‘HKEY_CURRENT_USER’,
‘HKEY_LOCAL_MACHINE’, ‘HKEY_USERS’, ‘HKEY_CURRENT_CONFIG’, ‘HKEY_DYN_DATA’);
function SearchKey(MainKey:word; // номер одного из 6 разделов реестра
SubKey:String; // подраздел, с которого начинается поиск
KeyF:String // имя подраздела, которое требуется найти
):string;
var I:dword; value:TRegKeyInfo; Strs:TStringList; path : string;
begin
Strs:=TStringList.create;
reg.RootKey:= Rtk[MainKey] ;
// задаем подраздел, в котором необходимо искать
reg.OpenKey(SubKey,false);
if reg.GetKeyInfo(value) then
Begin // при отсутствии подраздела – выход
if value.NumSubKeys=0 then exit;
reestr.GetKeyNames(Strs);
reestr.CloseKey;
For I := 1 to Value.NumSubKeys do
Begin // получение пути к разделам
if subkey=’\’ then path:=’\’+Strs.Strings[i-1] else path:=subkey+’\’+Strs.Strings[i-1];
if Strs.Strings[i-1]=KeyF then Listbox1.Items.add(Rks[MainKey]+Path); // запись результата
// вызов SearchKey ( ); — фактические параметры указать самостоятельно, исходя из логики процедуры поиска
End;
reg.CloseKey;
end;
end;
ВЫПОЛНЕНИЕ РАБОТЫ
Список заданий
- Написать приложение для создания в разделе HKEY_LOCAL_MACHINE\SOFTWARE подраздела, имя которого задается путем ввода с клавиатуры и записи в созданный раздел пары параметр-значение. Имя параметра и значение должны вводиться с клавиатуры.
- Добавить возможность редактирования с помощью разработанного приложения значений пар параметр-значение_строкового типа и проверить правильность выполнения редактирования на созданной в п.1 паре.
- Вывести список имен подразделов раздела, имя которого задается вводом с клавиатуры.
- Вывести список имен параметров пар заданного раздела.
- Вывести список типов значений параметров пар заданного раздела.
Примечание. п.1-п.5 выполнить с использованием функций Win32 API.
- Проверить работу фрагментов программ, приведенных в примерах 1 и 2.
Список индивидуальных заданий
- Разработать приложение для нахождения количества подразделов в каждом из 6 основных разделов реестра и самого длинного пути к подразделу. Данное приложение должно запускаться на данном ПК не более 5 раз (информацию о количестве запусков хранить в реестре).
- Разработать приложение для поиска в заданном разделе реестра параметра по его имени. Результат поиска – список путей к подразделам реестра, в которых хранится параметр с заданным именем. Дать предложения по повышению скорости работы приложения за счет использования дихотомического поиска.
- Разработать приложение для поиска в заданном разделе реестра всех параметров строкового типа, длина значений которых не превышает K (значения K и раздел реестра должны задаваться вводом с клавиатуры).
ОТЧЕТ О РАБОТЕ должен содержать:
1 Описание постановки задач, алгоритмов решения задач и его программной реализации.
- Полученные результаты.
Литература
Чен В., Берри В. Реестр Windows Nt для профессионалов. — СПб: «Издательство Питер», 1999.