Хранение данных в системном реестре

октября 12 2009 by admin in Администрирование

Прежде чем перейти к обсуждению хранения данных в системном реестре, я расскажу, как его правильно использовать. Как вы уже знаете, системный реестр является совместно используемым ресурсом, следовательно, он ограничен, и доступ к нему производится последовательно. Ваше приложение может хранить в реестре тысячи килобайт данных, однако вряд ли в его интересах будет использовать эту возможность по максимуму.
При рассмотрении хранения данных в реестре следует изучить два вопроса. Являются ли сохраняемые данные информацией о конфигурации приложения или они — данные общего назначения? (Например, вряд ли уместно сохранять в реестре документы текстового процессора.) Настолько ли велик объем данных (и настолько ли часто к ним обращаются), что хранить их в файле эффективнее, чем в реестре? (Например, словарь для проверки орфографии, используемый текстовым процессором, лучше хранить в файле.)
Принимая решения по этим вопросам, вы должны рассмотреть все «за» и «против», сравнить последствия загромождения файловой системы и неэффективного хранения больших объемов данных в реестре. Мы обсудим эффективное использование реестра в разделе «Эффективное использование реестра» этой главы.
Сохранить данные в реестре позволяет функция RegSetValueEx. Ее прототип:
LONG RegSetValueEx( HKEY hkey,
PCTSTR pszValueName, DWORD dwReserved, DWORD dwType, CONST BYTE «pbData, DWORD cbData);
Параметр hkey ссылается на раздел, в котором должно быть сохранено значение. Имя, которым вы хотите назвать значение, указывается вpszValueName. Если в этот параметр передать NULL или пустую строку, система сохранит данные в значении по умолчанию. Параметр dwType должен содержать одно из значений типов данных, перечисленных в табл. 5-2, в зависимости от типа сохраняемого значения. Параметр pbData указывает на сохраняемую в реестре информацию. Ее размер в байтах нужно передать в cbData.
Прежде чем продолжить, я хотел бы сказать о двух типах данных реестра, способных вызвать путаницу: REG_EXPAND_SZ и REG_MULTI_SZ. Первый очень похож на REG_SZ в том, что он также является оканчивающейся нулем Unicode-или ANSI-строкой, сохраняемой в реестре. Отличие же в том, что данные значений типа REG_EXPAND_SZ после извлечения из реестра, должны передаваться в функцию ExpandEnvironmentStrings.
Функции работы с реестром не преобразуют данные значений типа REG_EXPAND_SZ автоматически. За передачу строки в ExpandEnvironmentStrings отвечает ваше приложение.
Функция ExpandEnvironmentStrings объявлена так:
DWORD ExpandEnvironmentStrings( PCTSTR pszSrc, PTSTR pszDst, DWORD nSize);
Тип данных REG_MULTI_SZ вызывает непонимание чаще всего, так как он недостаточно четко описан в документации. В ней сказано, что значения типа REG_MULTI_SZ являются «оканчивающимся двумя символами нуля набором завершающихся нулем строк». Мне кажется, что эту фразу следует читать иначе: «В переменной типа REG_MULTI_SZ хранится набор оканчивающихся нулем строк, причем за последней строкой этого набора следуют два символа нуля». Не забывайте: получая или сохраняя данные этого типа, размер буфера следует подбирать с учетом всех нулей, завершающих строки, а также двойного нуля в самом конце. Ниже изображен пример мультистрокового значения реестра, состоящего из трех строк.