Несомненно, регистр (он же реестр) Windows очень полезная вещь. Ведь в нем можно хранить так много информации от количества программ вашей фирмы, ранее установленных на данном PC, и информации об их регистрации до разнообразных настроек окошек этих самых программ. Но для того чтобы все это там хранить, необходимо уметь работать с реестром, причем работать корректно, без ошибок.В данной статье будут разобраны основные функции работы с регистром в Delphi (легко портируемые при необходимости на С/С++), а также рассмотрены примеры пользовательских функций для более общих действий с регистром (тоже легко переносимые на С/С++). Итак, приступим…
Рассмотрим на примере. Допустим, вы написали очень (или не слишком) навороченную софтину и теперь хотите, чтобы богатенькие юзеры ею не просто так пользовались, а за денежку. То бишь, скачал юзер вашу софтинку с официального сайта вашей же фирмы Глюкософт, запустил, а она ему: «Заплати-ка ты, дружок, сначала $99.99 фирме Глюкософт, если хочешь получить все мои возможности, получи там у них код на такой-то номер, а потом и пользуйся!» Для этого вам необходимо при первом запуске сгенерировать два значения «Программа не зарегистрирована» и уникальный номер и где-то их сохранить. Уникальный номер нужен затем, чтобы предотвратить попытки доморощенных хакеров продавать за $9 универсальный код к вашей софтинке.
Первое и самое главное, что вам понадобится, это какая-либо переменная типа HKey. Этот тип описан в модуле windows.pas (как и все функции, описанные ниже) и представляет собой тип дескриптора ключа регистра (кто не знает, дескриптор это типа указателя, только круче :-)).
Затем при помощи функции RegOpenKey или RegOpenKeyEx открыть необходимый нам ключ регистра. Если при этом возникнет ошибка, значит, на 99% можно утверждать, что софтина запускается впервые, или что ваши записи в регистре были удалены.
Синтаксис у нее такой:
Где:
BaseKey дескриптор ранее открытого ключа или одна из мнемонических констант HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE или HKEY_USERS, обозначающих соответствующие базовые разделы регистра. Рекомендуется использовать только первые два: HKEY_CLASSES_ROOT информация об обрабатываемых расширениях, и HKEY_CURRENT_USER информация о текущем пользователе;
SubKey имя ключа, который вы хотите создать. При этом оно может содержать \ для спуска на один уровень вниз, но не должно начинаться или заканчиваться на этот самый \;
dwReserved припасено для будущих версий, должно быть 0;
samDesired флаг или комбинация флагов, отвечающих за способ открытия ключа; возможны следующие значения: KEY_READ просто чтение, KEY_SET_VALUE установить значение переменной в ключе, KEY_WRITE перезаписать ключ полностью, при этом все старые значения будут уничтожены;
ResKey дескриптор-приемник ключа.
В случае успешного выполнения функция возвращает значение ERROR_SUCCESS или NO_ERROR, в случае ошибки возвращается код ошибки.
Пусть мы установили, что запуск произведен впервые (открытие ключа вернуло ошибку). Значит, теперь нужно создать соответствующий вашей программе ключ. Сделать это можно при помощи функции RegCreateKeyEx.
Синтаксис у нее следующий:
Большинство параметров аналогичны RegOpenKeyEx:
samDesired может быть также KEY_ALL_ACCESS полный доступ с предварительным созданием; KEY_CREATE_SUB_KEY создание вложенного ключа;
pClass совершенно бесполезный параметр, поэтому лучше ставить значение nil;
dwOptions определяет тип создаваемого ключа; может быть REG_OPTION_NON_VOLATILE (постоянный ключ, используется по умолчанию; при этом информация, записанная в ключ, сохраняется и доступна после перезагрузки) или REG_OPTION_VOLATILE (временный ключ; в Win95/98 вообще игнорируется, во всех WinNT информация записывается во временную память и теряется при перезагрузке);
SecAttr в Win95/98 вообще игнорируется, во всех WinNT отвечает за параметры политики безопасности. Лучше ставить значение nil;
Disposition еще один совершенно ненужный параметр; лучше использовать адрес любой переменной типа integer или word со значением 0.
Ну а после того как мы создадим ключ, нам необходимо записать в него наши значения. Делается это с помощью функции RegSetValueEx со следующим синтаксисом:
Где:
ValueName имя переменной, значение которой устанавливается (если ее нет, то она будет создана);
dwType идентификатор типа переменной: REG_BINARY все виды двоичных типов переменных (напремер, boolean); REG_DWORD переменная типа dword; REG_SZ строковая переменная; REG_EXPAND_SZ строка с мнемоническими обозначениями переменных среды (например, %PATH%\GluckoSoft); REG_NONE неопределенный или сложный тип (например, какая-нибудь структура);
pData указатель на записываемые данные;
DataSize размер записываемых данных.
После всех этих операций нужно закрыть дескриптор ключа и освободить связанные с ним ресурсы системы. Делается это при помощи функции RegCloseKey с самым простым синтаксисом:
Теперь рассмотрим пользовательскую функцию, которая все это будет делать:
Значит, данные вы сохранили, окошко с сообщением юзеру выдали (наверняка сами это сможете сделать), тот зарегистрировался и получил код. Теперь необходимо код этот проверить на соответствие уникальному номеру и при соответствии отметить, что софтинка ваша зарегистрирована. Для этого вам понадобится уже знакомая функция RegOpenKeyEx с типом доступа KEY_READ и функция чтения RegQueryValueEx:
Почти все параметры вам уже знакомы.
pdwReserved зарезервировано, nil;
pdwType указатель на приемник идентификатора типа указанной переменной; заполняется по выполнении функции;
pData указатель на структуру-приемник данных;
pDataSize указатель (!) на размер приемника данных.
С их помощью вы считываете значение уникального номера, проверяете его на соответствие введенному коду и, при удовлетворительном результате, функцией RegSetValueEx изменяете значение переменной Registered на true.
Реализовать это можно примерно так:
Осталось совсем чуть-чуть. Предположим, что юзер вашей несомненно великолепной софтиной попользовался, но по какой-то причине решил ее удалить (мало ли, может, лучше нашел… причем, тоже вашу :-)). Удалять при этом придется порядком всякой всячины, и конечно же, вы для этого создали специальную процедуру/программу. Нужно обязательно не забыть удалить еще и записи в реестре (желательно, только от своей программы :-)). В этом вам поможет функция RegDeleteKey: Function RegDeleteKey(BaseKey:HKey; SubKey:PChar):dword.
Тут все понятно. Выглядеть это будет приблизительно вот так:
Нужно заметить, что при этом удаляется только подключ HKEY_CURRENT_USER\Software\GluckoSoft\Someware, а ключ HKEY_CURRENT_USER\Software\GluckoSoft остается. Чтобы избежать удаления информации других программ в этом ключе и, с другой стороны, захламления регистра пустыми ключами, можно, например, непосредственно в ключ HKEY_CURRENT_USER\Software\GluckoSoft добавить переменную, которая будет увеличиваться на 1 при установке новых программ вашей фирмы и уменьшаться на 1 при их удалении. Когда она станет равна нулю, смело производите удаление ключа HKEY_CURRENT_USER\Software\GluckoSoft. Заодно получится счетчик «рейтинга» вашей фирмы.
P.S. Вообще-то существует еще модуль registry.pas с описанием типа TRegistry, вроде бы призванного облегчить вам жизнь, но на практике гораздо удобнее и эффективнее использовать описанные выше функции. К тому же подключение этого модуля увеличивает размер ехе-файла.