|
Работа с реестром - теория
|
|
Главная страница \ Работа с реестром и INI файлами \ Работа с реестром - теория |
Работа с реестром в Delphi 1 | D1 | * |
{ Создаем список всех подразделов указанного раздела } procedure TForm1.Button1Click(Sender: TObject); var MyKey : HKey; { Handle для работы с разделом } Buffer : array[0..1000] of char; { Буфер } Err, { Код ошибки } index : longint; { Индекс подраздела } begin Err:=RegOpenKey(HKEY_CLASSES_ROOT,'DelphiUnit',MyKey); { Открыли раздел } if Err<> ERROR_SUCCESS then begin MessageDlg('Нет такого раздела !!',mtError,[mbOk],0); exit; end; index:=0; {Определили имя первого подраздела } Err:=RegEnumKey(MyKey,index,Buffer,Sizeof(Buffer)); while err=ERROR_SUCCESS do { Цикл, пока есть подразделы } begin memo1.lines.add(StrPas(Buffer)); { Добавим имя подраздела в список } inc(index); { Увеличим номер подраздела } Err:=RegEnumKey(MyKey,index,Buffer,Sizeof(Buffer)); { Запрос } end; RegCloseKey(MyKey); { Закрыли подраздел } end;
Работа с реестром в Delphi 2+ | D2+ | * |
В Delphi 4 для работы с реестром имеется класс TRegistry. В отличии от своего "младшего брата" (TRegistry в Delphi 1) он может работать со всеми ключами реестра, а не только с HKEY_CLASSES_ROOT.
Рассмотрим работу с TRegistry по шагам.
Если опустить пункт 4, то рабочий минимум
сводится к приведенному ниже коду
var
REG : TRegistry;
begin
REG := TRegistry.Create;
REG.Destroy;
end;
Далее необходимо рассмотреть (вкратце) основные свойства и методы TRegistry
Свойства
Свойства |
Назначение |
property RootKey: HKEY; |
Самое полезное свойство.
Допускает чтение и запись. Определяет корневой
ключ реестра. Допустимые значения: |
property CurrentPath: String; | Путь к текущему ключу |
property LazyWrite: Boolean; | "Ленивая запись". По умолчанию = true, что означает, что на момент возврата из функции закрытия ключа не гарантируется, что изменения в нем записаны в реестр. Если false, то на момент возврата из функции закрытия ключа гарантируется, что все изменения уже записаны в реестр. |
property CurrentKey: HKEY; | Открытый в настоящее время ключ реестра |
Методы
Procedure CloseKey;
Закрывает открытый в данный момент ключ реестра
и записывает в реестра все изменения (если
таковые были), произведенные в данном ключе.
Вызов CloseKey несколько раз или при отсутствии
открытого ключа не вызывает ошибки.
function CreateKey(const Key: String): Boolean;
Создает ключ Key (где Key - путь с разделителями "\",
например Software\Test. Имя корневого ключа в пути не
указывается !! Он задается через property RootKey.
Возвращает True при успешном создании.
function DeleteKey(const Key: String): Boolean;
Удалить ключ Key (аналогично CreateKey, только с
точностью до наоборот)
function DeleteValue(const Name: String): Boolean;
Удалить параметр с именем Name текущего ключа.
Очевидно, что предварительно необходимо открыть
этот ключ.
function GetDataInfo(const ValueName: String; var Value: TRegDataInfo): Boolean;
Получить информацию о параметре ValueName текущего
ключа - его тип и размер. При написании программ
применяется редко, т.к. программист и сам знает,
какого типа его параметры. А вот при написании
разного рода утилит для просмотра и
редактирования реестра он просто незаменим.
Типы:
TRegDataType = (rdUnknown, rdString, rdExpandString, rdInteger, rdBinary);
TRegDataInfo = record
RegData: TRegDataType; // Тип ключа
DataSize: Integer; // Размер данных
end;
Данная функция возвращает комплексную информацию о параметре, для получения данных о размере или типе можно применять GetDataSize и GetDataType
function GetDataSize(const ValueName: String): Integer;
Получить размер параметра ValueName текущего ключа в
байтах. Если - при ошибке. Для строкового
параметра размер учитывает в размере и один байт
для #0, завершающего строку .
function GetDataType(const ValueName: String): TRegDataType;
Получить тип текущего ключа.
function GetKeyInfo(var Value: TRegKeyInfo): Boolean;
Получить информацию о ключе. Возвращает
заполненную структуру:
TRegKeyInfo = record MaxSubKeyLen: Integer; // Количество подключей NumValues: Integer; // Количество параметров MaxValueLen: Integer; // Максимальная длина имени параметра MaxDataLen: Integer; // Максимальная длина данных FileTime: TFileTime; // Время последней записи ключа end;
Как очевидно из структуры, она предназначена для построения программ просмотра реестра. При успешном выполнении возвращает true.
procedure GetKeyNames(Strings: TStrings);
Заполняет указанный Strings списком под ключей
текущего ключа. Применяется для построения
программ просмотра реестра или в том случае,
когда количество подключей неизвестно. Например,
одна из моих программ создает в одном из ключей
несколько подключей с одинаковой структурой, но
их количество заранее неизвестно (настройки
пользователей).
procedure GetValueNames(Strings: TStrings);
Заполняет указанный Strings списком параметров
текущего ключа.
function HasSubKeys: Boolean;
Возвращает True, если текущий ключ имеет подключи и
False в противном случае
function KeyExists(const Key: String): Boolean;
Возвращает True, если ключ Key существует. Полезная
функция, рекомендуется применять ее перед
открытием ключей.
function LoadKey(const Key, FileName: String): Boolean;
Создает ключ Key и загружает в него данные из файла
с именем FileName. Полезно при написании
инсталляторов. Возвращает True при успешном
выполнении.
procedure MoveKey(const OldName, NewName: String; Delete: Boolean);
Копировать или переименовать ключ. В любом
случае копирует все из ключа OldName в NewName (со всеми
подключами). После копирования анализируется
Delete, и если он true, то ключ OldName уничтожается со
всем содержимым. Лично у меня не было потребности
в применении данной функции - она не требуется
программ и предначначена для построения
редакторов реестра.
function OpenKey(const Key: String; CanCreate: Boolean): Boolean;
Очень важная функция - с нее начинается работа с
ключом. Key - имя открываемого ключа. Если ключ с
указанным именем не найден и CanCreate=true, то
производится попытка создать ключ с указанным
именем. Возвращает признак успешности открытия
ключа, его обязательно следует анализировать.
function OpenKeyReadOnly(const Key: String): Boolean;
Тоже, что и OpenKey, но открытие идет в режиме
"только чтение"
Внимание !!!!!! Все функции типа Read** при вызове генерируют исключение, если параметр не найден. Это исключение следует отлавливать при помощи try except или проверять наличие параметра при помощи ValueExists перед его чтением.
function ReadBinaryData(const Name: String; var Buffer; BufSize: Integer): Integer;
Читает значение параметра с именем Name текущего
(открытого) ключа в Buffer размером BufSize.
function ReadBool(const Name: String): Boolean;
Считать значение параметра с именем Name типа Boolean
function ReadDate(const Name: String): TDateTime;
Считать значение параметра с именем Name типа дата
function ReadDateTime(const Name: String): TDateTime;
Считать значение параметра с именем Name типа
дата-время
function ReadTime(const Name: String): TDateTime;
Считать значение параметра с именем Name типа
время
function ReadFloat(const Name: String): Double;
Считать значение параметра с именем Name типа Double
function ReadInteger(const Name: String): Integer;
Считать значение параметра с именем Name типа Integer
function ReadString(const Name: String): String;
Считать значение параметра с именем Name типа String
function RegistryConnect(const UNCName: String): Boolean;
Подключить сетевой реестр машины UNCName (формат:
\\сетевое имя машины). Перед вызовом этой функции
программа должна установить RootKey в значение
HKEY_USERS или HKEY_LOCAL_MACHINE. При успешном соединении и
открытии удаленного реестра его RootKey ставится в
заданное перед вызовам значение свойства RootKey и
возвращается True.
procedure RenameValue(const OldName, NewName: String);
Переименовать параметр текущего ключа с именем
OldName в NewName.
function ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
Заменить место хранения ключа. Обычно ключи
хранятся в базовом файле реестра, нот вызовом
данной функции можно задать в качестве места
хранения ключа отдельный файл с именем FileName (его
следует предварительно создать при помощи savekey).
При каждой перезагрузке компьютера ключ Key будет
загружаться значениями, считываемыми из файла
этого файла FileName,т.е. по сути мы имеет дело с ульем
(hive) в терминологии Windows NT. Определение: Улей -
часть реестра (его ячейка). Улей является
дискретным набором ключей, подключей и
параметров, который находится вверху иерархии
реестра. Улей поддерживается одиночным файлом.
BackUpFileName - имя резервной копии, которая создается
перед перезаписью данных ключа Key. Если кого
интересуют подробности, то следует почитать
книгу по реестру Windows NT, главы типа "Ульи и
файлы" и "Целостность и восстановление улья в
реестре". При разработке практических
приложений я не разу не применял этот вызов.
function RestoreKey(const Key, FileName: String): Boolean;
Открывает указанный ключ и перезаписывает его
данные и подключи данными из файла FileName.
function SaveKey(const Key, FileName: String): Boolean;
Сохраняет все параметры указанного ключа и всех
его подключей в файле FileName. Может применяться
совместно с LoadKey и RestoreKey для создания и
восстановления ключей реестра.
function UnLoadKey(const Key: String): Boolean;
Удалить улей Key из реестра.
function ValueExists(const Name: string): Boolean;
Проверить, существует ли в текущем ключе
параметр с именем Name. Весьма полезная функция,
т.к. чтение несуществующего параметра приводит к
исключительной ситуации
procedure WriteBinaryData(const Name: String; var Buffer; BufSize: Integer);
Записать в параметр с именем Name данные из буфера
Buffer размером BufSize. Если параметр существовал, то
он будет перезаписан. Если параметр не
существовал, то он будет создан. Это справедливо
и для всех последующих процедур записи
параметров
Остальные процедуры записи - WriteBool, WriteCurrency,WriteDate,WriteDateTime, WriteExpandString, WriteFloat, WriteInteger, WriteString, WriteTime имеют по два параметра - (имя ключа, значение ключа).
Ну вот, класс описали, теперь приведем парочку примеров.
Пример 1 - запись. var REG : TRegistry; begin REG := TRegistry.Create; REG.RootKey:=HKEY_LOCAL_MACHINE; REG.OpenKey('Software\Test',true); REG.WriteBool('Test1',true); REG.WriteInteger('Test2',12); REG.CloseKey; REG.Destroy; end;
Данный пример создает (если его не было) или открывает ключ реестра HKEY_LOCAL_MACHINE\Software\Test и записывает в него два параметра типа Boolean и Integer.
Пример 2 - чтение. var REG : TRegistry; B : Boolean; I : Integer; begin REG := TRegistry.Create; REG.RootKey:=HKEY_LOCAL_MACHINE; if REG.OpenKey('Software\Test',false) then begin if REG.ValueExists('Test1') then B:=REG.ReadBool('Test1') else ShowMessage('Параметр Test1 не найден'); if REG.ValueExists('Test2') then I:=REG.ReadInteger('Test2') else ShowMessage('Параметр Test2 не найден'); end else ShowMessage('Ключ HKEY_LOCAL_MACHINE\Software\Test не найден'); REG.CloseKey; REG.Destroy; end;
Данный пример открывает ключ (контролируя, есть ли он) и пытается читать параметры с проверкой, существуют ли они.