В данном примере рассматривается, как можно хранить различные данные о приложении в реестре ОС Windows.
Теория
Реестр Windows или системный реестр (англ. Windows Registry) — иерархически построенная база данных параметров и настроек в большинстве операционных систем Microsoft Windows. Реестр содержит информацию и настройки для аппаратного обеспечения, программного обеспечения, профилей пользователей, предустановки. Большинство изменений в Панели управления, ассоциации файлов, системные политики, список установленного ПО фиксируются в реестре. Реестр Windows был введён для упорядочения информации, хранившейся до этого во множестве INI-файлов. Полная статья о реестре здесь.
Основные разделы реестра операционной системы Windows
Раздел |
Описание |
HKEY_CLASSES_ROOT |
Содержится информация о зарегистрированных в Windows типах файлов (что и позволяет открывать их по двойному щелчку), классах и их свойствах, хранит параметры запуска программ при открытии файла с помощью проводника (связи между приложениями, типами файлов, а также информация об OLE). Является ссылкой на раздел HKEY_LOCAL_MACHINE\Software\Classes. |
HKEY_CURRENT_USER |
Содержатся настройки оболочки пользователя (например, Рабочего стола, меню "Пуск" и др.). Если на компьютере работает один пользователь и используется обычный вход в Windows, то значения раздела берутся из подраздела HKEY_USERS\.DEFAULT |
HKEY_LOCAL_MACHINE |
Содержится информация, относящаяся к данному компьютеру для всех пользователей: драйверы, установленное программное обеспечение и его настройки. |
HKEY_USERS |
Содержит настройки оболочки Windows для всех пользователей. Именно из этого раздела информация копируется в раздел HKEY_CURRENT_USER. Все изменения в HKEY_CURRENT_USER автоматически переносятся в HKEY_USERS |
HKEY_CURRENT_CONFIG |
Cодержится информация о конфигурации устройств Plug&Play, сведения о конфигурации компьютера с переменным составом аппаратных средств, сведения о настройках оборудования, используемых локальным компьютером при запуске системы (текущей конфигурации). Является ссылкой на HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Hardware Profiles\Current. |
Конечным элементом дерева реестра являются ключи или параметры, среди которых можно выделить три основных типа:
-
строковые (например, "C:\Program Files");
-
двоичные (например. 06 31 B2 8C). Максимальная длина такого ключа 16Кб;
-
тип DWORD. Этот тип ключа занимает 4 байта и отображается в шестнадцатеричном и в десятичном виде (например, 0x00000001 (1) — в скобках указано десятичное значение ключа).
Посмотреть и отредактировать данные реестра можно встроенной в ОС Windows утилитой Regedit.
Практика
Для начала работы создадим новый проект Windows Forms Application. Назовем его WorkWithRegistry.
Изменим свойства формы:
Свойство |
Значение |
(Name) |
MainForm |
Size |
300; 138 |
StartPosition |
CenterScreen |
Text |
Работа с реестром Windows |
На форму MainForm добавим контролы Label, TextBox, 2 Button и изменим их свойства:
label1
Свойство |
Значение |
Location |
12; 9 |
Text |
Значение для хранения в реестре |
textBox1
Свойство |
Значение |
(Name) |
textBoxDataToSave |
Location |
15; 25 |
Size |
265; 20 |
button1
Свойство |
Значение |
(Name) |
ButtonSaveData |
Location |
60; 51 |
Size |
176; 23 |
Text |
Сохранить данные в реестре |
button2
Свойство |
Значение |
(Name) |
ButtonDeleteData |
Location |
60; 80 |
Size |
176; 23 |
Text |
Удалить данные в реестре |
Основные классы для работы с реестром в .NET – Registry и RegistryKey , которые находятся в пространстве имён Microsoft.Win32.
Поэтому для работы с этими классами подключим пространство имен Microsoft.Win32 к нашей программе.
Полные описания свойств и методов классов на MSDN:
Приведу только некоторые методы класса RegistryKey:
Метод |
Описание |
CreateSubKey |
Создание нового параметра реестра или открытие существующего. Название не чувствительно к регистру |
DeleteSubKey |
Удаление существующего параметра |
DeleteSubKeyTree |
Удаление существующего раздела и вложенных подразделов |
DeleteValue |
Удаление значения существующего параметра |
OpenSubKey |
Получение значения параметра только для чтения |
SetValue |
Установка значения |
GetValue |
Получение значения параметра |
Close |
Закрытие параметра и запись его содержимого на постоянной основе |
Во всем реестре нас интересует только раздел HKEY_CURRENT_USER, являющийся ссылкой, линком на определенный подраздел HKEY_USERS. В нем, в подразделе Software хранится вся информация об установленных программах и их данные. Этот подраздел и предназначен для использования в интересах прикладных программ.
Для упрощения работы создадим 3 метода в классе MainForm.
//RegistrySet - функция для добавления данных в реестр. Если ветки реестра не существует - она создается. //Для универсализации мы все значения ключей передаем в виде строки. Не забываем приводить к нужному типу при использовании! //Section - название нашего раздела в ветке HKEY_CURRENT_USER\Software\ //Key - название ключа в разделе //KeyValue - значение ключа private void RegistrySet(string Section, string Key, string KeyValue) { //Путь к ключу в реестре string RegistryPath; //Формируем путь к нашему разделу RegistryPath = "Software\\" + Section; //Переменная для работы с реестром RegistryKey MyRegistryKey; //Проверяем есть ли наш раздел try { MyRegistryKey = Registry.CurrentUser.OpenSubKey(RegistryPath); if (MyRegistryKey == null) { //Раздела нет - создаем и открываем для чтения и добавления MyRegistryKey = Registry.CurrentUser.CreateSubKey(RegistryPath); } else { //Открываем на запись в существующий MyRegistryKey = Registry.CurrentUser.OpenSubKey(RegistryPath, true); } //Пробуем записать значения ключей MyRegistryKey.SetValue(Key, KeyValue); //Выведем сообщение об успехе MessageBox.Show("Параметры сохранены."); //Сохраняем значения в реестре MyRegistryKey.Close(); } catch (System.Exception err) { //Если есть ошибки, то выводим сообщение с описанием этой ошибки MessageBox.Show("Произошла ошибка при работе с реестром : " + err.Message); } }
//RegistryGet - функция для чтения данных из реестра. Если ветки реестра и ключей не существует - они создаются. //Для универсализации мы все значения ключей передаем в виде строки. Не забываем приводить к нужному типу при использовании! //Section - название нашего раздела в ветке HKEY_CURRENT_USER\Software\ //Key - название ключа в разделе private string RegistryGet(string Section, string Key) { //Путь к ключу в реестре string RegistryPath; //Переменная для хранения значения ключа string KeyValue = ""; //Переменная для работы с реестром RegistryKey MyRegistryKey; //Формируем путь к нашему разделу RegistryPath = "Software\\" + Section; //Проверяем есть ли наш раздел try { MyRegistryKey = Registry.CurrentUser.OpenSubKey(RegistryPath, true); if (MyRegistryKey == null) { //Раздела нет - создаем MyRegistryKey = Registry.CurrentUser.CreateSubKey(RegistryPath); } //Считываем данные ключа KeyValue = (string) MyRegistryKey.GetValue(Key); //Если ключ не существует - создаем if (KeyValue == null) { MyRegistryKey.SetValue(Key, ""); } //Выведем сообщение об успехе MessageBox.Show("Параметры загружены."); //Сохраняем значения в реестре MyRegistryKey.Close(); } catch (System.Exception err) { //Если есть ошибки, то выводим сообщение с описанием этой ошибки MessageBox.Show("Произошла ошибка при работе с реестром : " + err.Message); } //Возвращаем полученное значение return KeyValue; }
//RegistryDelete - функция для удаления данных из реестра //Внимание! Удаляет все данные из раздела Section, включая все ключи и подразделы //Section - название раздела в ветке HKEY_CURRENT_USER\Software\ private void RegistryDelete(string Section) { //Путь к разделу в реестре string RegistryPath; //Переменная для работы с реестром RegistryKey MyRegistryKey; //Формируем путь к нашему разделу RegistryPath = "Software\\" + Section; //Проверяем есть ли наш раздел try { MyRegistryKey = Registry.CurrentUser.OpenSubKey(RegistryPath, true); if (MyRegistryKey != null) { //Удаляем все данные в корне раздела foreach (string valueName in MyRegistryKey.GetValueNames()) { MyRegistryKey.DeleteValue(valueName); } //Если подраздел существует, то удаляем все данные во всех вложенных подразделах foreach (string subKeyName in MyRegistryKey.GetSubKeyNames()) { using (RegistryKey tempKey = MyRegistryKey.OpenSubKey(subKeyName)) { foreach (string valueName in tempKey.GetValueNames()) { tempKey.DeleteValue(valueName); } } } //Удаляем раздел и все вложенные подразделы Registry.CurrentUser.DeleteSubKeyTree(RegistryPath); //Выведем сообщение об успехе MessageBox.Show("Параметры удалены."); } //Сохраняем значения в реестре MyRegistryKey.Close(); } catch (System.Exception err) { //Если есть ошибки, то выводим сообщение с описанием этой ошибки MessageBox.Show("Произошла ошибка при работе с реестром : " + err.Message); } }
В обработчик нажатия первой кнопки поместим следующий код для записи данных в реестр:
private void ButtonSaveData_Click(object sender, EventArgs e) { //Записываем данные в ключ реестра HKEY_CURRENT_USER\Software\MySoft\SavedData RegistrySet("MySoft", "SavedData", textBoxDataToSave.Text); }
В обработчик нажатия второй кнопки поместим следующий код для удаления данных из реестра:
private void ButtonDeleteData_Click(object sender, EventArgs e) { //Удаляем данные из реестра RegistryDelete("MySoft"); }
В обработчик события FormLoad для формы MainForm поместим следующий код для чтения данных из реестра:
private void MainForm_Load(object sender, EventArgs e) { //Считываем данные из ключа реестра HKEY_CURRENT_USER\Software\MySoft\SavedData textBoxDataToSave.Text = RegistryGet("MySoft", "SavedData"); }
В результате получаем программу, которая записывает в реест данные из TextBox'а по нажатию первой кнопки, удаляет их из реестра по нажатию второй кнопки и считывает их из реестра при запуске.
Исходник проекта находится здесь.
Обсудить проект можно здесь.
Источники
|