logo search
Программирование в среде Delphy / Программирование в среде Delphi

32. Работа с реестром

Системный реестр операционной системы Windows представляет собой общедоступную древовидную базу данных для хранения настроечной информации как самой Windows, так и других программ, установленных на компьютере. В первых версиях Windows все настройки программ и самой операционной системы хранились в специальных текстовых файлах с расширением «ini». С развитием системы таких файлов становилось все больше и больше. Они были разбросаны по разным каталогам, и стало очень сложно управлять такой системой. Начиная с Windows 95, вся настроечная информация стала заноситься в одно место – реестр. Работа с реестром в Delphi осуществляется через модуль Registry, а работа с реестром вне Delphi – системной программой RegEdit.exe.

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

Весь реестр разделяется на 5 ключевых областей:

• HKEY_CLASSES_ROOT – содержит информацию о расширениях файлов, классах и зарегистрированных в системе COM серверах. Содержимое этого ключа дублируется в разделе

HKEY_ LOCAL_MACHINE\SOFTWARE\Classes;

• HKEY_CURRENT_USER – содержит множество настроек программного обеспечения (информацию о конфигурации рабочего стола, клавиатуры и информацию о параметрах меню Пуск) текущего пользователя, т.е. того пользователя, который в настоящий момент зарегистрирован в системе. Реестр копирует содержимое одного из подразделов в разделе HKEY_USERS в данный раздел и по окончании работы его обновляет;

• HKEY_LOCAL_MACHINE – содержит информацию, относящуюся к компьютеру: местонахождение драйверов, параметры настроек установленных на компьютере программ и COM–серверов. Он самый крупный и самый важный из всех разделов реестра. В нем содержится в одном из подразделов копия ключа HKEY_CLASSES_ROOT и все возможные варианты в зависимости от текущей аппаратной конфигурации содержимого раздела HKEY_CURRENT_CONFIG;

• HKEY_USERS – содержит описания настроек компьютера для всех зарегистрированных в системе пользователей. Подраздел Default является разделом HKEY_CURRENT_USER для конфигурации пользователя Windows по умолчанию;

• HKEY_CURRENT_CONFIG – содержит описание текущей конфигурации оборудования компьютера и является отражением одной из ветвей раздела HKEY_LOCAL_MACHINE\Config, в котором описаны все созданные в системе конфигурации оборудования. Когда конфигурация меняется, меняется и содержимое раздела HKEY_CURRENT_CONFIG – он начинает «отражать» уже другую ветвь раздела HKEY_LOCAL_MACHINE\Config.

Физически, содержимое реестра находится в нескольких файлах и это зависит от версии Windows. Например, для Windows XP основные настройки реестра находятся в каталоге %SystemRoot%\System32\Config. Точный список файлов реестра можно посмотреть в разделе

HKEY_LOCAL_MACHINE\System \CotnrolSet\Control\HiveList\

Для работы с реестром в Delphi нужно:

• подключить модуль Registry, объявив его в операторе Uses,

• создать переменную типа TRegistry и вызвать ее конструктор,

• выполнить работы с реестром с помощью методов класса TRegistry,

• освободить память, занимаемую переменной типа TRegistry.

Остановимся на описании некоторых свойств и методов класса TRegistry:

• Property RootKey: HKEY; – определение текущего корневого ключа (один из возможных пяти, приведенных выше);

• Property CurrentKey: HKEY; – получение текущего открытого ключа реестра;

• Function OpenKey(const Key: String; CanCreate: Boolean): Boolean; – открытие ключа Key в текущем корневом каталоге, но если такого ключа нет, то он будет создан при CanCreate=True. Функция возвращает истину, если операция открытия ключа успешно выполнена;

• Function ReadString(const Name: String): String; – чтение значения параметра Name строкового типа;

• Procedure WriteString(const Name, Value: String); – запись значения Value в параметр Name строкового типа;

• Function CreateKey(const Key: String): Boolean; – создание нового ключа Key в текущем ключе;

• Procedure CloseKey; – закрытие открытого ключа и запись изменений в реестр;

• Function DeleteKey(const Key: String): Boolean; – удаление из реестра ключа Key. Корневые ключи не поддаются удалению;

• Function DeleteValue(const Name: String): Boolean; – очистка значения параметра Name;

• Function ReadInteger(const Name: String): Integer; – чтение значения параметра Name целого типа;

• Procedure WriteInteger(const Name: String; Value: Integer); – запись значения параметра Name целого типа.

Рассмотрим пример записи в реестр некоторой информации о своей программе.

Uses …., Registry; // Подключаем к программе модуль Registry

………..

Var Reg:TRegistry; // Определяем указатель на реестр

Begin

Reg:=TRegistry.Create; // Выделяем память под реестр

// Устанавливаем корневой ключ

Reg.RootKey:=HKEY_LOCAL_MACHINE;

// Создаем в ключе Software ключ MyProgram

Reg.OpenKey(’Software\MyProgram’,True);

// Создаем в текущем ключе параметр ID и записываем в него

// серийный номер нашей программы: ABCD–1234.

Reg.WriteString(’ID’,’ABCD–1234’);

Reg.CloseKey; // Закрываем ключ

Reg.Destroy;// Освобождаем память, выделенную ранее переменной Reg

End;

Работать с реестром можно также с использованием программы RegEdit.exe путем создания текстового файла с нужными изменениями и последующего вызова из Delphi программы RegEdit с передачей ей текстового файла через параметры командной строки.

Операции, которые мы сделали в предыдущем примере, можно оформить и следующим образом:

// Первая строка текстового файла для формата NT4

Const RegID=’REGEDIT4’+#13#10;

// Строка ключа

RegPath:=’[HKEY_LOCAL_MACHINE\SOFTWARE\MyProgram]’+

#13#10;

// Задание имени параметра и его значения

RegNew=’”ID”=”ABCD–1234”’+#13#10;

Var RegFile:TFileStream; // Переменная файлового потока

RegCmd:String; // Командная строка

P:Pchar; // Указатель на строку с нулевым символом в конце строки

Begin

// Создаем текстовый файл

RegFile:=TFileStream.Create(’MyFile.reg’,fmCreate);

// Записываем в него управляющую строку

RegFile.Write(RegID[1], Length(RegID));

// Записываем текущий ключ реестра

RegFile.Write(RegPath[1], Length(RegPath));

// Записываем определения параметров для текущего ключа

RegFile.Wtite(RegNew[1], Length(RegNew));

// Закрываем файл

RegFile.Free;

// Определяем командную строку

RegCmd:=’RegEdit /s ’+’MyFile.reg’;

// Преобразуем обычную строку в указатель P

StrPCopy(P, RegCmd);

// Вызываем из Delphi программу EditReg и вносим в реестр изменения

WinExec(P, SW_MINIMIZE);

// Удаляем текстовый файл

If FileExists(’MyFile.reg’) then DeleteFile(’MyFile.reg);

End;

Можно просканировать весь реестр в поисках заданных ключей и значений параметров с помощью следующей рекурсивной процедуры:

// Поиск в реестре значений параметров

Procedure Scanreg(skey,findpar:String;valpars:Tstringlist;

var reg:Tregistry);

// SKey – ключ просмотра

// FindPar – имя искомого параметра

// ValPars – список найденных значений параметров

// Reg – указатель на реестр

var st:Tstringlist; // Внутренний список строк

i:integer;s,s1:String;

dt:TRegDataType;

Begin

// Открытие текущего ключа

if reg.OpenKeyReadOnly(skey) then Begin

st:=Tstringlist.create;

reg.GetValueNames(st); // Получение списка параметров

for i:=0 to st.count-1 do Begin // Проход по списку

if st.Strings[i]=findpar then Begin

dt:=reg.GetDataType(findpar); // Получение типа параметра

if dt=rdstring then Begin

s:=reg.ReadString(st.Strings[i]); // Получение значения параметра

valpars.add(s); // Добавление значения в список значений параметров

end;

end;

end;

st.Clear; // Очистка внутреннего списка параметров

reg.GetKeyNames(st); // Получение списка ключей

for i:=0 to st.count-1 do Begin // Проход по списку ключей

s1:=st.Strings[i]; // Получение значения ключа

// Сканирование текущего ключа

scanreg(skey+'\'+s1,findpar,valpars,reg);

end;

reg.CloseKey; // Закрытие текущего ключа

st.Free; // Очистка списка ключей

end;

end;

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

procedure TForm1.Button1Click(Sender: TObject);

var s:string;

ss:TStringList; // Указатель на список адресов электронной почты

begin

reg1:=Tregistry.Create; // Подключение к реестру

// Установка корневого ключа

reg1.RootKey:=HKEY_CURRENT_USER;

ss:=Tstringlist.Create; // Выделение памяти под список адресов

s:=''; // Вначале ключ полагаем равным пустой строке

s1:='SMTP Email Address'; // Имя параметра электронной почты

Scanreg(s,s1,ss,reg1); // Сканируем реестр

if ss.Count>0 then Begin

Memo1.Lines:=ss; // Записываем адреса электронной посты в Memo1

end;

ss.Free; // Освобождаем память списка

reg1.CloseKey; // Закрываем реестр

end;