C чтение реестра. Изменяем меню кнопки "пуск"

29.03.2019

Реестр Windows является одной из самых загадочных частей операционной системы, которая позволяет настраивать и модифицировать почти все аспекты Windows. Некоторые работают с реестром постоянно, но большинство людей имеют о нем лишь слабое представление и не совсем уверены, как создавать пользовательские разделы и параметры. Итак, давайте попробуем разобраться, что же такое реестр Windows.

Что такое реестр Windows

Реестр Windows – это не что иное, как совокупность различных конфигураций и настроек системы.

Его можно рассматривать как базу данных, хранящую практически всю важную информацию. Эта информация включает в себя все то, что связанно с системой аппаратного обеспечения, настройками приложений, установленными программами, профилями пользователей и т.д. Windows обращается к реестру постоянно, поскольку, как уже было сказано, в нем хранится вся важная информация, и операционной системе гораздо быстрее и проще управлять всем из одного места, чем возиться с отдельными файлами конфигурации, расположенными в разных местах.

Компоненты реестра Windows

Реестр Windows 10 состоит из трех основных компонентов – ключи корневого уровня, разделы и параметры.

Ключи корневого уровня содержат в себе разделы, которые имеют свой собственный набор параметров.

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

  • HKEY_CLASSES_ROOT (HKCR): этот ключ используется для связывания и внедрения объектов (Object Linking and Embedding, OLE) и ассоциации типов файлов. Это ключ, где Windows связывает файлы с их соответствующими программами, чтобы пользователь мог открывать и взаимодействовать с ними.
  • HKEY_ CURRENT_ USER (HKCU): этот раздел реестра Виндовс хранит все данные, настройки на уровне пользователя и конфигурации, связанные с вошедшим в систему пользователем. Не только Windows, но и другие программы хранят здесь данные, относящиеся к текущему пользователю.
  • HKEY_LOCAL_MACHINE (HKLM): независимо от статуса пользователя, этот ключ содержит все системные разделы, в том числе любые аппаратные настройки, параметры программного обеспечения и т.д. Поскольку HKLM содержит большую часть всей системной информации, он является одним из самых открытых корневых ключей Windows.
  • HKEY_USERS (HKU): как следует из названия, этот корневой ключ содержит параметры всех пользователей, включая вошедших и вышедших из системы, так что не путайте этот ключ с HKCU.
  • HKEY_CURRENT_CONFIG (HKCC): проще говоря, это псевдо корневой ключ, поскольку он является прямой ссылкой на текущие параметры профиля оборудования в корневом ключе HKLM.

Параметры разделов

Каждый из этих корневых ключей имеет свои собственные разделы, а каждый раздел имеет свои собственные параметры. В каждом разделе можно создать 6 различных типов параметров, а значения этих параметров полностью зависят от целевой программы и/или требований к конфигурации.

А вообще есть четыре основных типа данных, используемых в редакторе реестра Windows любой версии - 7,8 или 10:

  • Строковый параметр: состоит из простого читаемого текста и является одним из наиболее часто используемых параметров в реестре Windows.
  • Двоичный параметр: как следует из названия, этот параметр содержит только двоичные данные (0, 1). Часто используется для включения или выключения определенной функции.
  • Параметр DWORD (32 бита): похож на двоичный параметр, но способен хранить любое целое число в диапазоне от 32 бит. Предназначен для работы с 32-битными системами, но также используется в 64-битных системах в целях обеспечения обратной совместимости.
  • Параметр QWORD (64 бита): этот параметр почти как DWORD, но способен нести любое целое число в диапазоне от 64 бит. Можно сказать, что QWORD предназначен для работы с 64-битными системами.

Как открыть редактор реестра Windows

Этот способ открытия реестра будет работать независимо от установленной версии Windows - 7,8 или 10:

Нажмите клавишу + клавишу R, чтобы открыть окно «Выполнить». Введите или и нажмите Enter или OK. Если появится окно контроля учетных записей (UAC), нажмите «Да».

Основной исполняемый файл редактора реестра находится в каталоге C:\Windows . Так что можно открыть эту папку и запустить файл regedit.exe напрямую, или можно просто создать ярлык regedit.exe в удобном для вас месте.

Редактор реестра: для 64-разрядных и 32-разрядных Windows

Реестр в 64-битных версиях Windows состоит из 32-битных и 64-битных разделов. Многие из 32-битных разделов имеют те же самые названия, что и их 64-битные аналоги, и наоборот.

64-разрядная версия (используется по умолчанию) (regedit.exe) отображает как 64-битные, так и 32-битные разделы. В 64-разрядной версии редактора реестра 32-битные ключи отображаются в следующем разделе реестра:

HKEY_LOCAL_MACHINE\Software\WOW6432Node

Просматривать и редактировать 64-битные и 32-битные разделы и параметры можно с помощью 64-разрядной версии редактора. Для просмотра или редактирования 64-битных ключей необходимо использовать 64-разрядную версию редактора реестра (regedit.exe). Редактировать и просматривать 32-битные ключи и значения можно также с помощью 32-разрядной версии (%systemroot\%Syswow64). Чтобы открыть 32-разрядную версию редактора реестра, выполните следующие действия:

  • Откройте диалог «Выполнить».
  • Введите %systemroot%\syswow64\regedit и нажмите OK.

Примечание

Перед открытием 32-разрядной версии нужно закрыть 64-разрядную версию редактора реестра (и наоборот). Однако можно открыть второй экземпляр редактора реестра. Например, если 64-битная версия редактора уже запущена, введите команду %systemroot%\syswow64\regedit -m , чтобы запустить 32-разрядную версию редактора.

Создание новых разделов и параметров

Создавать разделы и параметры очень просто. Но прежде чем что-либо делать, пожалуйста, создайте резервную копию реестра Windows, так как любые неверные настройки или удаление важных элементов может стать причиной критических ошибок.

Чтобы создать резервную копию, в окне редактора нажмите «Файл -> Экспорт», введите имя файла и сохраните его в надежном месте.

Чтобы создать новый раздел, щелкните правой кнопкой мыши на ключе корневого уровня и выберите «Создать -> Раздел». Новый раздел будет выглядеть как папка, и по умолчанию будет называться что-то вроде «Новый раздел #1». Разумеется, раздел можно всегда переименовать. Такая же процедура применяется всякий раз, когда нужно создать новый подраздел.

Чтобы создать новый параметр, щелкните правой кнопкой мыши в пустой области правой панели редактора и выберите нужный параметр. Созданному параметру нужно присвоить название; название полностью зависит от конкретных требований.

Чтобы присвоить параметру значение, дважды щелкните на нем и введите значение. Опять же, значение зависит от программы или конкретных настроек.

Права доступа к разделам реестра

По аналогии с правами и разрешениями на определенные объекты в файловой системе NTFS, такая же защита предусмотрена и для разделов реестра.

Еще со времен Windows Vista большое количество ОС-специфических ключей реестра, хранящих настройки Windows, находятся под защитой Windows Resource Protection, поэтому нельзя просто взять и удалить или изменить их. Вы не сможете сделать этого, не став их владельцем и не установив разрешения (права доступа) на них. К счастью, операционная система позволяет и это, но ручной способ чересчур муторный, поэтому лучше использовать простую утилиту , которая автоматизирует весь этот процесс.

На этом все! Надеюсь, написанное выше помогло вам лучше понять реестр Windows и его основные компоненты. Обменивайтесь мнениями и опытом в комментариях ниже!

Отличного Вам дня!

Реестр Windows является неотъемлемой частью каждой операционной системы Microsoft Windows. Он действует так, же как каталог, в котором хранятся все виды пользовательских настроек, конфигурационных данных о приложениях, файловые ассоциации и т.д. Если попробовать дать определение этого чудо-компонента, то реестр - компонент операционной системы компьютера, который в иерархической базе данных хранит важнейшие установки и информацию о приложениях, системных операциях и пользовательской конфигурации. Таким образом, возможность работы с реестром – это что-то, что не может быть упущено из виду разработчиком Windows приложений.

В этой статье я попытаюсь рассказать Вам, как использовать возможности этого монстра в c++ приложениях.Мы подойдем к этой ситуации с помощью специальных API-функций, которые позволяют работать с реестром. В этой статье мы узнаем, как создать консольное приложение, позволяющее открыть указанный раздел, создать и установить новое значение, создать новый подраздел, удалить подраздел и значение. При этом мы не будем использовать никаких дополнительных библиотек.

Однако для начала разберемся со структурой реестра, а затем приступим к написанию программы, объясняя правильное использование каждой функции реестра.

Я не буду подробно описывать структуру этого монстра от Microsoft. Я всего лишь расскажу достаточную информацию для понятия этой статьи. Всю, необходимую Вам, информацию Вы сможете найти в сети.

Структура реестра

Важно понять структуру реестра на данном этапе усваивания материала, что бы потом у нас не возникло непонимания по ходу дальнейшего изучения. В этом разделе мы очень быстро и кратко «пробежимся» по реестру, т.к. на подробное его изучение потребуется много времени и места. Представьте реестр как папку. В ней могут быть другие папки и файлы. Теперь разберемся с обозначением. Реестр Windows содержит два элемента: раздел (key) и значение (value). В нашей аналогии разделы выступают в роли папок, в то время как значения – файлы. В действительности, значения – это пары «имя-данные». Это значит, что значение делится на две части: имя и данные. Имя используется как идентификатор, а данные как часть фактических данных. Каждый раздел имеет значение, но, помимо значения, раздел может иметь и подраздел. Весь реестр делится на логические разделы, которые называются «ульи» (hives). Всего таких разделов пять.

Теперь зайдите в редактор реестра (Пуск-Выполнить-regedit) и посмотрите его структуру. На всякий случай сделайте копию реестра. Хотя наша программа будет безобидной для него, лишним это действие все равно не будет. Для тех, кто не знает, я расскажу, как сделать копию реестра.

Что бы сделать backup своего реестра выполните следующие действия:
1) Нажмите "Пуск", "Выполнить" и введите "regedit".
2) Появится окно редактора реестра. Нажмите в верхней части окна "Файл", потом "Экспорт". Введите любое имя для сохраняемого резервного файла реестра, тип файла выберите "Файлы реестра *.reg". Ниже, под надписью "Диапазон экспорта" выберите "Весь реестр", нажмите "Сохранить".

Теперь разберем некоторые функции, которые нам понадобятся для написания задуманного.

Базовые функции реестра

В этой статье мы узнаем, как читать, изменять и записывать данные в реестр. По ходу этого раздела мы рассмотрим некоторые из основных функций для открытия подразделов реестра и работы с ними. Функции, с которыми мы будем работать, Вы сможете найти в файле windows.h. Эти функции работают с любой версией Windows.

Наша первая функция - RegOpenKeyEx (). Эта функция открывает указанный раздел реестра и возвращает ERROR_SUCCESS при успешном выполнении. Важно понять, что эта функция открывает уже существующий раздел; она не создаст новый раздел, если такового не существует.

Вторая функция, которую мы будем использовать – это функция RegSetValueEx(), которая создает новое значение в нашем разделе, открытом с помощью первой рассмотренной функции.

Следующие три функции позволят добавить новый раздел и удалить данные с реестра. RegCreateKeyEx () будет использоваться для создания нового ключа, а при удалении значения и ключа мы будем вызывать RegDeleteValue () и RegDeleteKey () соответственно. Если Вы пользователь Windows Vista или Microsoft Server 2008, то вместо функции RegDeleteValue () Вам следует вызвать функцию RegDeleteTree(). Хотя чаще возникает потребность писать универсальное приложение, которое будет работать с любым продуктом Microsoft. Поэтому делайте проверку WINWER в своем коде.

Ну и последняя функция, которая нам понадобится в данном уроке – это функция, которая уничтожает (а лучше сказать освобождает) переменную, в которой будет храниться дескриптор, открытого с помощью первой функции, раздела. Имя этой функции RegCloseKey().
Теперь мы знакомы с функциями (а точнее с их именами и назначением), которые нам пригодятся, и переходим к написанию кода нашей программы.

Как понятно из названия данного раздела, тут будет код нашей программы. Но перед тем, как писать код необходимо создать пустое консольное приложение. Я использую Microsoft Visual Studio 2010. О том, как создать, необходимый нам, тип приложения подробно описано в последнем номере журнала () в статье "Что нам стоит GUI построить".

Тут я приведу сразу весь код, а потом прокомментирую его, дав подробное описание каждой функции.
int main()
{
HKEY hKey;
DWORD dwDisposition;
unsigned char szStr;
szStr="1"; szStr="\0";

if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\VR_Online\\Test"), 0, KEY_ALL_ACCESS, &hKey)!=ERROR_SUCCESS)
cout<<"\nError opening the desired subkey (doesn"t exist?).\n";
else
{

cout<<"\nThe value of the key was set successfully.\n";
else
cout<<"\nError setting the value of the key.\n";
}
RegCloseKey(hKey);

RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\VR_Online\\Test\\Another SubKey"), 0, NULL, 0, 0, NULL, &hKey, &dwDisposition);
if (dwDisposition != REG_CREATED_NEW_KEY && dwDisposition != REG_OPENED_EXISTING_KEY)
cout<<"\nError creating the desired subkey (permissions?).\n";
else
cout<<"\nThe subkey was successfully created.\n";
RegCloseKey(hKey);


{

cout<<"\nString Value value successfully removed.\n";
else
cout<<"\nError removing the specified value (permissions?).\n";
}
else
cout<<"\nError opening the specified subkey path (doesn"t exist?).\n";

RegCloseKey(hKey);

if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\VR_Online\\Test"), 0, KEY_ALL_ACCESS, &hKey)==ERROR_SUCCESS)
{

cout<<"\nAnother SubKey key successfully removed.\n";
else
cout<<"\nError removing the specified key (permissions?).\n";
}
else
cout<<"\nError opening the specified subkey path (doesn"t exist?).\n";

RegCloseKey(hKey);


{

cout<<"\nTest key successfully removed.\n";
else
cout<<"\nError removing the specified key (permissions?).\n";
}
else
cout<<"\nError opening the specified subkey path (doesn"t exist?).\n";

RegCloseKey(hKey);


{

cout<<"\nVR_Online key successfully removed.\n";
else
cout<<"\nError removing the specified key (permissions?).\n";
}
else
cout<<"\nError opening the specified subkey path (doesn"t exist?).\n";

RegCloseKey(hKey);

Ну, что же, теперь надо разобраться, что тут написано.
HKEY hKey;
DWORD dwDisposition;
unsigned char szStr;
szStr="1"; szStr="\0";

В первой строке мы объявили переменную hKey, типа HKEY. Это переменная – дескриптор указанного «улья» реестра. Во второй строке объявлена переменная, dwDisposition, которая нужна для определения, является ли подраздел созданным или он уже существовал, и может ли он быть открыт успешно. Данная переменная понадобится нам для функции RegCreateKeyEx (). Подробно о значениях, которые функция загоняет в эту переменную, Вы сможете узнать на msdn.com в описании данной функции. Далее мы объявили массив типа unsigned char, состоящий из двух элементов. Первому элементу мы присвоили значение «1», а второму – конец строки. Эта переменная (массив) будет служить данными для нашего имени при создании нового значения функцией RegSetValueEx().
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\VR_Online\\Test"), 0, KEY_ALL_ACCESS, &hKey)!=ERROR_SUCCESS)
cout<<"\nError opening the desired subkey (doesn"t exist?).\n";
else
{
if (RegSetValueEx(hKey, TEXT("String Value"), NULL, REG_SZ, szStr, sizeof(szStr))==ERROR_SUCCESS)
cout<<"\nThe value of the key was set successfully.\n";
else
cout<<"\nError setting the value of the key.\n";
}
RegCloseKey(hKey);

В вышеприведенном куске кода мы проверяем успешное выполнение функции RegOpenKeyEx(). Описание этой функции приведено выше. Т.к. эта функция открывает уже существующий раздел то, выполнение этой функции выдаст нам сообщение об ошибке. Что бы этого избежать, можно создать «вручную» этот раздел, а можно и программно. Давайте создадим его «вручную», т.к. далее вы узнаете, как создавать разделы программно. Что бы «вручную» создать раздел, необходимо войти в редактор реестра (Пуск-Выполнить-regedit), выбрать нужным нам «улей» (в нашем случае HKEY_LOCAL_MACHINE). В нем выбираем раздел «SOFTWARE» (кстати, в нашей функции, как и во всех функциях работы с реестром регистр букв не важен), жмем на него правой клавишей мыши и «Создать»-«Раздел». Присваиваем разделу имя VR_Online, а потом в нем создаем подраздел с именем «Test» аналогичным образом.

Первый параметр функции – раздел реестра, который мы хотим открыть. Второй – имя подраздела. В данном примере мы открыли подраздел “SOFTWARE” По поводу третьего параметра документация Microsoft говорит только то, что он зарезервирован и должен быть равным нулю. Четвертый параметр – уровень доступа. В данном примере мы получили полный доступ к этому разделу. Однако не всегда раздел позволят получить к нему полный доступ, в таком случае функция будет выполнена неудачно. Последний параметр этой функции – указатель на переменную, которой будет передан дескриптор открытого раздела.

Если раздел существует, то мы устанавливаем ему значение (помните я говорил, что значение есть пара «имя-данные»?). Именем значения будет «String Value», а данными – наш массив szStr. Создаем мы значение с помощью функции RegSetValueEx(),в которую последовательно передаем дескриптор раздела, название переменной, тип данных (с типами данных Вы можете ознакомиться на msdn - http://msdn.microsoft.com/en-us/library/ms724884 (v=vs.85).aspx), сейчас только скажу, что этот тип значит строковую переменную. Последние два параметра – указатель на буфер данных и его размер. О результате выполнения этой функции на экран выводится сообщение. В конце мы вызываем функцию RegCloseKey().

Далее мы программно создадим подраздел. Делается это с помощью функции RegCreateKeyEx ().
RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\VR_Online\\Test\\Another SubKey"), 0, NULL, 0, 0, NULL, &hKey, &dwDisposition);

if (dwDisposition != REG_CREATED_NEW_KEY && dwDisposition != REG_OPENED_EXISTING_KEY)
cout<<"\nError creating the desired subkey (permissions?).\n";
else
cout<<"\nThe subkey was successfully created.\n";
RegCloseKey(hKey);

Первые два параметра, а так же предпоследний параметр, понятны исходя из уже известного материала. Про последний параметр я рассказал выше, при описании, объявленных в начале функции main(), переменных. Третий параметр зарезервирован и должен равняться нулю. Четвертый – тип класса раздела. В пятом параметре могут содержаться дополнительные опции, значение которых можно глянуть в описании этой функции на msdn. Следующий параметр определяет спецификатор доступа к данному разделу. Седьмой параметр является атрибутом безопасности. Он определяет, может ли данный раздел (а точнее его дескриптор) наследоваться дочерными процессами. Если он в значении NULL, то дескриптор не может быть унаследован.

А теперь очистим наш реестр от всего того, что мы создали.
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\VR_Online\\Test"), 0, KEY_ALL_ACCESS, &hKey)==ERROR_SUCCESS)
{
if (RegDeleteValue(hKey, TEXT("String Value"))==ERROR_SUCCESS)
cout<<"\nString Value value successfully removed.\n";
else
cout<<"\nError removing the specified value (permissions?).\n";
}
else
cout<<"\nError opening the specified subkey path (doesn"t exist?).\n";

RegCloseKey(hKey);

if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\VR_Online\\Test"), 0, KEY_ALL_ACCESS, &hKey)==ERROR_SUCCESS)
{
if (RegDeleteKey(hKey, TEXT("Another SubKey"))==ERROR_SUCCESS)
cout<<"\nAnother SubKey key successfully removed.\n";
else
cout<<"\nError removing the specified key (permissions?).\n";
}
else
cout<<"\nError opening the specified subkey path (doesn"t exist?).\n";

RegCloseKey(hKey);

if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\VR_Online"), 0, KEY_ALL_ACCESS, &hKey)==ERROR_SUCCESS)
{
if (RegDeleteKey(hKey, TEXT("Test"))==ERROR_SUCCESS)
cout<<"\nTest key successfully removed.\n";
else
cout<<"\nError removing the specified key (permissions?).\n";
}
else
cout<<"\nError opening the specified subkey path (doesn"t exist?).\n";

RegCloseKey(hKey);

if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software"), 0, KEY_ALL_ACCESS, &hKey)==ERROR_SUCCESS)
{
if (RegDeleteKey(hKey, TEXT("VR_Online"))==ERROR_SUCCESS)
cout<<"\nVR_Online key successfully removed.\n";
else
cout<<"\nError removing the specified key (permissions?).\n";
}
else
cout<<"\nError opening the specified subkey path (doesn"t exist?).\n";

RegCloseKey(hKey);

Что ж…тут только две новых функции: RegDeleteValue() и RegDeleteKey(). Их назначение понятно из их названий, а параметры понятны из усвоенного материала и простой интуиции. Как Вы могли заметить, эта часть кода обладает значительным минусом – нельзя удалить сразу раздел VR_Online со всем его содержимым. Удалять надо, начиная с «глубин» подраздела. Но заинтересовавшиеся читатели могут попробовать написать рекурсивную функцию, которая сама будет это делать.

Я вот еще раз перечитал свою статью и понял, что чего-то тут не хватает. Дело в том, что чаще приходится использовать данные реестра, а не изменять их или добавлять данные в реестр. Поэтому, как бонус, тем, кто дочитал до этого места, я рассажу, как с помощью реестра получить адрес стартовой страницы Internet Explorer, а затем изменить его. И хотя этим браузером мало кто пользуется, технология получения подобной информации одинакова. Для начала установим значение стартовой страницы. Сделать это можно тремя способами: через редактор реестра вручную, через браузер и программно. Т.к. наша тема связана с реестром, а программно мы изменим значение позже, то сейчас мы это сделаем вручную.

Заходим в «Пуск» - «Выполнить» и пишем regedit. В редакторе реестра проходи по пути «Software\\Microsoft\\Internet Explorer\\Main» и находим там значение Start Page. Жмем на эту переменную два раза и в появившемся диалоговом окне в поле «значение» указываем, например, «http://google.com”.

Следующий код Вы можете использовать как раз для достижения нашей «бонусной» цели.
TCHAR lpData={0};
DWORD buffersize = sizeof(lpData);

If (RegOpenKeyEx (HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Internet Explorer\\Main"),NULL,KEY_READ,&hKey)==ERROR_SUCCESS)
{
if (RegQueryValueEx(hKey,TEXT("Start Page"),NULL,NULL,(LPBYTE) lpData,&buffersize)==ERROR_SUCCESS)
{
cout<<"\nYour current Internet start page is ";
wcout< }
else
cout<<"\nError getting the specified value.\n"
}
else
cout<<"\nError opening the specified subkey path (doesn"t exist?).\n";

RegCloseKey (hKey);

TCHAR *Val=_T("http://сайт");
DWORD size=_tcslen(Val);

if (RegOpenKeyEx (HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Internet Explorer\\Main"),NULL,KEY_ALL_ACCESS,&hKey)==ERROR_SUCCESS)
{
if (RegSetValueEx(hKey, TEXT("Start Page"),0, REG_SZ, (BYTE*)Val,2*size)==ERROR_SUCCESS)
{
cout<<"\nNow your Internet start page is ";
wcout< }
else
cout<<"\nError setting the value of the key.\n";
}
else
cout<<"\nError opening the specified subkey path (doesn"t exist?).\n";

RegCloseKey (hKey);

Как видно из кода, у нас только одна неизвестная нам функция. RegQueryValueEx(). Она позволяет получить значение, которое хранится в указанном разделе. Первые два параметра этой функции, я думаю, не стоит описывать. Третий зарезервирован. Четвертый параметр содержит тип получаемого значения. Два последних параметра определяют буфер, в который будет записано значение, и его размер соответственно. Ну а далее мы изменяем значение этой переменной с помощью,уже известной нам, функции.

Что бы Вам было более ясно происходящее в данном коде, я расскажу Вам о типах char, TCHAR и о кодировке UNICODE.

Вообще, по теме этого раздела стоит писать отдельную статью, которая по размерам не будет уступать этой статье, но я этого делать не буду, т.к. не обладаю глубокими знаниями в этой области. Я расскажу то, чего хватит для понимания моей статьи.

Тип char используется для ANSI строк, т.е. строк, символы которых занимают один байт (8 бит). То есть допускается всего 256 (2 в восьмой степени) символов. Гляньте в таблицу ASCII, и Вы увидите, что все символы там не выходят за значение 255. Этого количества символов хватает нам с Вами с нашим-то алфавитом. И тип char идеально подходит для содержания этих символов.

Но давайте подумаем о японцах. У них существуют различные наборы символов, такие как, например катакана (katakana), хирагана (hiragana), канжи (kanji) и ромаджи (romaji). Невозможно впихнуть все эти символы в диапазоне от нуля до 255. Поэтому и используется кодировка Unicode, которая может содержать 65535 (2 в шестнадцатой степени) символов.

В основном тип TCHAR и используется для описания Unicode строк. В отличие от типа char, tchar занимает 2 байта. Это и объясняет умножение на двойку длины строки, в которой содержится новое имя стартовой страницы.
if (RegSetValueEx(hKey, TEXT("Start Page"),0, REG_SZ, (BYTE*)Val,2*size)==ERROR_SUCCESS)

Т.к. продукты Microsoft используют по всему миру, то программисты этой компании потрудились над тем, что бы разработчикам приложений под их основной продукт было удобно пользоваться своим языком, а не вездесущим английским. Поэтому почти все API функции «зависят» от Unicode.
Для удобной работы с Unicode – строками существует файл tchar.h. В нем собрано огромное количество макросов для работы TCHAR. Макрос TEXT, взятый как раз из этой библиотеки, позволяет компилировать программу и под Unicode и под ANSI. Так же там описан оператор wcout, который работает аналогично cout, но для TCHAR-типа.
Я думаю, что материал этого раздела хоть как-то пролил свет на Ваше представление о происходящем.

Вот и все. Мы сделали все, что задумали в начале урока и даже больше. Я не стал наполнять эту статью скриншотами с результатами выполнения различных частей кода этой программы. Вы сами можете это сделать, поэтапно комментируя определенные функции и заглядывая в редактор реестра. Надеюсь, что кто-то нашел в этой статье что-нибудь полезное.

В заключение скажу, что реестр очень удобная вещь для разработчика. В нем вы можете хранить настройки своих приложений и использовать параметры других приложений, а так же настроек системы. Но не стоит изменять или удалять те значения и разделы, в ненадобности которых вы не уверены.

Если по каким-то причинам, у Вас не работает код, который я приводил в пример, ниже Вы можете скачать рабочий.cpp файл этой программы.

Спасибо за внимание.

Written by: Сергей Дубовик aka SD
E-mail: eval(unescape("%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%22%6d%61%69%6c%74%6f%3a%73%64%62%6f%78%40%74%75%74%2e%62%79%22%3e%73%64%62%6f%78%40%74%75%74%2e%62%79%3c%2f%61%3e%27%29%3b"))

Реестр

Во всех версиях Windows, начиная с Windows 95, системный реестр является центральным хранилищем всей конфигурационной информации, касающейся настройки Windows, пользовательских предпочтений, а также установленного программного и аппаратного обеспечения. Почти любое коммерческое программное обеспечение в наши дни использует реестр для хранения информации о себе.

Компонентам СОМ тоже требуется сохранять информацию о себе в реестре для того, чтобы клиенты могли к ним обращаться. Среда.NET Framework и предлагаемая в ней концепция установки с нулевым воздействием (zeroimpact installation) делает реестр чуть менее существенным для приложений, поскольку создаваемые с ее помощью сборки получаются полностью самодостаточными, т.е. никакой информации в реестр для них помещать не требуется, даже если они являются разделяемыми.

Вдобавок в.NET Framework предлагается концепция изолированного хранилища (приложения могут хранить информацию, касающуюся каждого пользователя, в файлах) и.NET Framework самостоятельно заботится об отдельном хранении данных для каждого зарегистрированного в системе пользователя.

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

Например, если приложение должно появляться в диалоговом окне Add/Remove Programs (Установка и удаление программ) панели управления, потребуется внести соответствующие записи в системный реестр. Системный реестр также может понадобиться для обеспечения обратной совместимости с унаследованным кодом.

Как и следовало ожидать от такой обширной библиотеки, как.NET, в ней поставляются классы, которые позволяют получать доступ к реестру. Таких классов два - Registry и RegistryKey , и оба они находятся в пространстве имен Microsoft.Win32 . Прежде чем переходить к рассмотрению этих классов, давайте вкратце ознакомимся со структурой самого реестра.

Реестр имеет иерархическую структуру, во многом похожую на структуру файловой системы. Обычно для просмотра и изменения содержимого реестра применяются две утилиты: regedit и regedt32 . Утилита regedit является стандартной и поставляется во всех версиях Windows, начиная с Windows 95. Утилита regedt32 входит в состав Windows NT и Windows 2000, и по сравнению с regedit менее дружественная к пользователю, но зато она позволяет получать доступ информации, связанной с безопасностью, которую regedit просматривать не позволяет.

В Windows Server 2003 эти утилиты были объединены в единый новый редактор, который называется просто regedit. В ходе обсуждений здесь имеется в виду утилита regedit, поставляемая в Windows 7, которую можно запустить, введя regedit в диалоговом окне для запуска программ либо в командной строке.

На рисунке показано, как выглядит окно regedit при запуске этой утилиты в первый раз. На этом рисунке видно, что regedit имеет пользовательский интерфейс в стиле "дерево/список", который похож на интерфейс проводника Windows и в точности отражает иерархическую структуру самого реестра. Однако вскоре будут показаны и некоторые важные отличия:

В файловой системе узлы верхнего уровня представляют разделы дисков - С:\ , D:\ и т.д. В реестре эквивалентом разделов дисков являются разделы реестра (registry hive) . Изменять существующие разделы не допускается - они являются фиксированными и всего их семь, хотя в интерфейсе regedit видны только пять из них, которые перечислены ниже:

HKEY_CLASSES_ROOT (HKCR)

содержит детали, касающиеся типов файлов в системе (.txt, .doc и т.д.), и о том, какие приложения способны открывать файлы каждого из этих типов. Также содержит регистрационную информацию обо всех компонентах СОМ (она обычно занимает больше всего места в реестре, поскольку в Windows в настоящее время поставляется огромное количество разнообразных СОМ-компонентов).

HKEY_CURRENT_USER (HKCU)

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

HKEY_LOCAL_MACHINE (HKLM)

представляет собой огромный раздел, в котором содержатся детали, касающиеся всего установленного на машине программного и аппаратного обеспечения. Также включает в себя раздел HKCU, который сам по себе не является отдельным разделом, а просто удобным отображением ключа реестра HKLM/SOFTWARE/Classes.

HKEY_USERS (HKUSR)

содержит детали, касающиеся предпочтений всех пользователей. Как не трудно догадаться, он тоже содержит разделы HKCU, которые являются просто отображением соответствующих ключей HKEY_USERS.

HKEY_CURRENT_CONFIG (HKCF)

содержит детали, касающиеся конфигурации установленного на машине оборудования.

В остальных двух корневых разделах размещается информация, которая является временной и часто изменяющейся:

HKEY_DYN_DATA

является общим контейнером для любых текущих данных, которые требуется сохранять где-нибудь в реестре.

HKEY_PERFORMANCE_DATA

содержит информацию, касающуюся производительности функционирующих в текущий момент приложений.

Внутри разделов находится древовидная структура ключей реестра. Каждый из них во многом напоминает папку или файл в файловой системе. Однако между ними имеется одно очень важное отличие. В файловой системе различаются файлы (в которых хранятся данные) и папки (в которых главным образом содержатся другие файлы или папки), а в реестре присутствуют только ключи. В каждом ключе могут содержаться как данные, так и другие ключи.

Если ключ содержит данные, то они представлены последовательностью значений. Каждое значение имеет ассоциированное с ним имя, тип данных и собственно данные. Вдобавок ключ имеет безымянное значение по умолчанию.

Всю эту структуру можно увидеть, используя утилиту regedit. На рисунке показано содержимое ключа HKCU\Console:

Записи в системном реестре могут иметь формат одного из трех типов данных:

    REG_SZ (приблизительно соответствует экземпляру строки в.NET, но это сходство не точное, поскольку типы данных реестра не являются типами данных.NET);

    REG_DWORD (приблизительно соответствует типу uint);

    REG_BINARY (массив байт).

Приложение, предусматривающее сохранение каких-то данных в реестре, будет делать это за счет создания ряда ключей, причем обычно внутри ключа HKLM\Software\<Название компании>. Обратите внимание, что в этих ключах вовсе не обязательно должны содержаться какие-либо данные. Порой сам факт существования ключа позволяет приложению получать те данные, которые ему необходимы.

Как уже говорилось, доступ к реестру позволяют получать два класса из пространства имен Microsoft.Win32: Registry и RegistryKey. Экземпляр RegistryKey представляет ключ реестра. В этом классе есть методы для просмотра дочерних ключей, для создания новых ключей, а также для чтения и изменения значений в существующих ключах, т.е. можно выполнять все, что обычно требуется делать с ключами реестра, в том числе устанавливать для них уровни безопасности. Именно этот класс применяется для выполнения большей части работы с реестром.

В отличие от него, Registry представляет собой класс, который позволяет получать эксклюзивный доступ к ключам реестра для выполнения простых операций. Другим предназначением класса Registry является предоставление экземпляров RegistryKey, представляющих ключи наивысшего уровня, т.е. разделы, которые позволяют осуществлять навигацию по реестру. Предоставляются эти экземпляры через семь статических свойств со следующими именами: ClassesRoot, CurrentConfig, CurrentUser, DynData, LocalMachine, PerformanceData и Users. Каким разделам соответствуют эти свойства, должно быть вполне очевидно.

Например, для получения экземпляра RegistryKey, представляющего ключ HKLM, потребуется написать такой код:

RegistryKey hklm = Registry.LocalMachine;

Процесс получения ссылки на объект RegistryKey называется открытием ключа . Хотя можно было бы ожидать, что, поскольку реестр имеет такую же иерархическую структуру, что и файловая система, методы, предлагаемые классом RegistryKey, должны быть похожими на те, что реализованы в DirectoryInfo, на самом деле это не так. Часто способ доступа к реестру отличается от способа использования файлов и папок, и RegistryKey реализует методы, отражающие это.

Наиболее очевидное отличие связано с тем, как открывается ключ в определенном месте реестра. Класс Registry не имеет никакого общедоступного конструктора, который можно было бы использовать, равно как не имеет и методов, которые позволяли бы переходить к ключу по имени напрямую. Вместо этого добираться до нужного ключа придется от самого верхнего раздела.

Если необходимо создать экземпляр объекта RegistryKey, то единственно возможный способ предусматривает начать с соответствующего статического свойства класса Registry и оттуда уже двигаться вниз. То есть, например, для чтения данных из ключа HKLM\Software\Microsoft потребуется получить на него ссылку следующим образом:

RegistryKey hklm = Registry.LocalMachine; RegistryKey hkSoftware = hklm.OpenSubKey("Software"); RegistryKey hkMicrosoft = hkSoftware.OpenSubKey("Microsoft");

Доступ к ключу подобным образом позволяет осуществлять только чтение. Если необходимо выполнить запись каких-то данных в ключ (в том числе запись его значения, а также создание или удаление его непосредственных дочерних элементов), потребуется использовать другую переопределенную версию OpenSubKey . Она принимает во втором параметре значение типа bool, указывающее, должен ли доступ к ключу предоставляться не только для чтения, но и для записи. Например, чтобы получить возможность изменить ключ Microsoft (имея права системного администратора), потребуется написать следующий код:

RegistryKey hklm = Registry.LocalMachine; RegistryKey hkSoftware = hklm.OpenSubKey("Software"); RegistryKey hkMicrosoft = hkSoftware.OpenSubKey("Microsoft", true);

Кстати, поскольку в этом ключе содержится информация, используемая приложениями Microsoft, в большинстве случаев этот конкретный ключ модифицировать не стоит.

Метод OpenSubKey() вызывается в случаях, когда ожидается, что ключ уже существует. Если ключа там не оказывается, OpenSubKey() возвращает ссылку null. Чтобы создать ключ, необходимо использовать метод CreateSubKey() (который автоматически предоставляет доступ как для чтения и записи к ключу через возвращаемую ссылку):

RegistryKey hklm = Registry.LocalMachine; RegistryKey hkSoftware = hklm.OpenSubKey("Software"); RegistryKey hkMine = hkSoftware.CreateSubKey("MyOwnSoftware");

Способ, которым работает метод CreateSubKey(), является довольно интересным. Он создает ключ, если его не существует, а если ключ существует, метод просто возвращает экземпляр RegistryKey, который представляет существующий ключ. Причина, по которой этот метод ведет себя подобным образом, связана с тем, как обычно используется реестр. В реестре в целом содержатся подлежащие длительному хранению данные наподобие конфигурационной информации для Windows и различных приложений. Поэтому необходимость создавать ключ явным образом возникает не очень часто.

Гораздо чаще приложениям требуется проверять наличие некоторой информации в реестре - другими словами, создавать ключи, если они еще не существуют, и ничего не делать, если ключи уже там есть. Метод CreateSubKey() просто идеально позволяет удовлетворить такую потребность. В отличие от ситуации с FileInfo.Open(), в случае применения CreateSubKey() случайное удаление каких-нибудь данных исключается. Если же на самом деле необходимо удалить какие-то ключи реестра, потребуется вызвать метод DeleteSubKey() .

Учитывая важность реестра для Windows, в этом есть смысл. Вряд ли кому-то понравится перспектива случайно вывести систему Windows из строя, просто удалив несколько важных ключей во время отладки самостоятельно написанного кода C#, который работает с системным реестром.

После обнаружения подлежащего чтению или модификации ключа можно с помощью метода SetValue() или GetValue() , соответственно, установить либо извлечь данные из него. Оба эти метода принимают в качестве параметра строку с именем значения, но SetValue() также требуется дополнительно передать в качестве параметра ссылку на объект, который содержит детали, касающиеся значения. Поскольку по определению этот параметр должен представлять собой ссылку на объект, он на самом деле может быть ссылкой на любой класс. По типу предоставляемого класса метод SetValue() и будет определять тип для значения - REG_SZ, REG DWORD или REG_BINARY. Например:

RegistryKey hkMine = HkSoftware.CreateSubKey("MyOwnSoftware") ; hkMine.SetValue("MyStringValue", "Hello World"); hkMine.SetValue("MyIntValue", 20);

В этом коде для ключа устанавливаются два значения: MyStringValue с типом REG_SZ и MyIntValue с типом REG_DWORD.

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

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

Итак, что же вообще собой представляет реестр, и где он находится? Реестр - это как бы большая база данных операционной системы, в которой хранятся различные настройки вашего компьютера. Настройки, как программного обеспечения, так и аппаратного (монитор, видеокарта и т.д.). Структура реестра такова: существуют 5 основных разделов (их еще иногда называют «кусты»), в каждом из которых находятся подразделы, и, наконец, в каждом из этих подразделов имеются параметры (или «ключи»). Изменением этих параметров («ключей») мы и займемся.

Как же нам добраться до реестра? Очень просто! Для этого предусмотрена специальная программа, входящая в состав Windows XP (она имеется и во всех предыдущих версиях Windows). Называется она Regedit. Для того чтобы ее открыть, нужно в меню Start (Пуск) выбрать Run (Выполнить). В появившемся окошке пишите regedit (без кавычек). Слева мы наблюдаем разделы и подразделы, а справа находятся ключи (или параметры).

Давайте быстренько пробежимся по всем разделам и узнаем, за что каждый из них отвечает.

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

HKEY_CURRENT_USER
Все настройки текущего пользователя записаны здесь.

HKEY_LOCAL_MACHINE
В этом разделе хранятся все настройки вашего компьютера (то есть информация как аппаратного, так и программного обеспечения).

HKEY_USERS
Тут содержатся настройки всех пользователей.

HKEY_CURRENT_CONFIG
Сюда занесены сведения о настройках оборудования (текущей конфигурации вашего ПК).

Теперь кратко рассмотрим, как записываются параметры или ключи. Каждый ключ имеет свое имя, тип и значение. С именем все ясно, а вот на типе нужно остановиться немного подробнее. Если вы имели дело с программированием, то и с этим вопросом у вас никаких проблем не возникнет. А вот для тех, кому слово «программирование» ничего не говорит, я немножко объясню, рассмотрев типы по отдельности.

REG_BINARY
Это бинарный (или двоичный) тип. То есть сюда входят только две цифры - 1 и 0. Он не очень привычен для нас, но для компьютера типа лучшего, чем этот, просто не найти… :-)

REG_DWORD
Это целочисленный тип. Многие параметры служб и драйверов устройств имеют этот тип и отображаются в двоичном, шестнадцатеричном или десятичном форматах.

REG_EXPAND_SZ
Это строковый тип.

REG_MULTI_SZ
Тип, похожий на предыдущий. Но, это не одна строка, а набор строк.

REG_SZ
То же строковый тип, но в отличие от REG_EXPAND_SZ, это строка фиксированной длины.

Ну, вот вроде бы и разобрались немного с реестром, теперь давайте перейдем непосредственно к настройке нашей любимой Windows XP. Вначале мы будем настраивать/оптимизировать такую любимую и многими используемую программу, как Internet Explorer. Что ж приступим.

Для начала давайте спрячем некоторые настройки от «левых» пользователей, чтобы никто не мог изменить параметры вашего браузера. Скроем вкладку General (Общее). Для этого найдем раздел HKEY_CURRENT_USER\Software\Policies\Microsoft. В нем создайте еще один подраздел (new > key) и назовите его Internet Explorer. Затем в только что созданном подразделе сформируйте еще один key (на подразделе Internet Explorer нажимаем правой кнопкой мышки, выбираем new > key). Назовите этот ключик Control Panel. Все, теперь выделяем Control Panel и в правой части окна Regedit создаем новый параметр типа DWORD с названием GeneralTab. Присвойте этому параметру значение 1 или 0 (если захотите вновь вернуть вкладку General (Общее).

Теперь замаскируем вкладку Security (Безопасность). Для чего в этом же разделе (Internet Explorer > Control Panel) создаем параметр типа DWORD. Имя параметра SecurityTab, значение - 1.

Продолжая продвижение в таком важном деле, как конспирация, скроем далее Privacy (Конфиденциальность). Создаем параметр PrivacyTab типа DWORD, со значением 1. Далее у нас идет вкладка Content Tab (Содержание). Вновь создаем параметр ContentTab, того же типа и с тем же значением. Еще у нас осталось 3 вкладки для скрывания. Создаем дополнительно три параметра с именами ConnectionsTab (убираем вкладку Подключение), ProgramsTab (это вкладка Программы), AdvancedTab (вкладка Дополнительно). Все эти параметры имеют тип DWORD и значение, равное 1.

Все, со скрытием настроек закончили. Когда вы что-то качаете из Инета с помощью браузера, то все это сохраняется в папке C:\Documents and Settings\Current User\Desktop. Чтобы файлы помещались в другую папку, в разделе HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer поменяйте значение параметра Download Directory на путь к нужному каталогу.

Если вам не нравится, как раскрашена панель инструментов, то вы можете самостоятельно поменять рисунок. Для этого в HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Toolbar создайте параметр с именем BackBitmap (наподобие параметра String Value). Значение - это путь к файлу с рисунком, который вам нравится (расширение *.bmp), например, c:\picture.bmp (только без кавычек).

Для того чтобы изменить заголовок программы Internet Explorer, в разделе HKEY_CURRENT_USER\ Software\ Microsoft\ Internet Explorer\ Main нужно создать параметр типа String Value с именем Window Title. Значение этого параметра - это и есть название окна Internet Explorer.

Если вы не хотите, чтобы кто-то мог изменить панель инструментов, в разделе HKEY_CURRENT_USER\ Software\ Microsoft\ Windows\ CurrentVersion\ Policies\ Explorer создайте параметр NoToolbarCustomize типа DWORD. В качестве значения параметра необходимо выставить 1.

С Internet Explorer немного разобрались. Это, конечно, далеко не все настройки, которые можно сделать с помощью реестра, существует масса других возможностей. Мы же далее перейдем к различным настройкам Windows XP (так сказать, общим настройкам системы).

Если вы - не единственный хозяин своего компьютера, но хотите, чтобы ваши настройки никто не менял, то есть два способа осуществить задуманное. Например, выставили вы на рабочем столе особенно полюбившиеся вам обои. Пришел кто-то другой, и все поменял… Как решить данную проблему? Конечно, можно просто создать несколько пользователей, но это не самый выгодный вариант. Так как для каждого из них понадобится дополнительные ресурсы. Намного проще решить эту проблему, просто убрав вкладку Desktop (Рабочий стол) из настроек экрана. Для этого зайдите в раздел HKEY_CURRENT_USER\ Software\ Microsoft\ Windows\ CurrentVersion\ Policies и создайте тут новый key с именем System. В этом ключе создайте параметр NoDispBackgroundPage типа DWORD. Присвойте значение 1. Все, теперь никто не изменит ваши обои:-). Чтобы скрыть вкладки Themes (Темы) и Appearance (Оформление), в только что созданном ключе нужно сформировать еще один параметр NoDispAppearancePage того же типа, с тем же значением, что и предыдущий. Теперь вообще никто ничего не поменяет!

Но и это еще не все. Давайте в этом меню уберем все полностью. Итак, у нас еще осталось две вкладки - это Screen Saver (Заставка) и Setting (Параметры). Для того чтобы спрятать их, нужно создать еще два параметра типа DWORD: NoDispScrSavPage (для скрытия Заставки) и NoDispSettingsPage (для скрытия Параметры). Эти два параметры должны иметь значение 1 (если захотите все вернуть обратно, то выставьте 0).

Теперь предлагаю немножко поиздеваться над какой-нибудь программкой, которая входит в состав Windows. Например, это будет Media Player. Для этого в разделе HKEY_CURRENT_USER\Software\Policies\Microsoft нужно создать один ключик: WindowsMediaPlayer. Здесь (только уже в правом окошке) создаем параметр TitleBar типа String Value, в значение вписываем название плейера.

Если уже речь пошла о Media Player, то давайте поэкспериментируем с ним еще. Активизируем его DVD-возможности. Для этого в разделе HKEY_CURRENT_USER\Software\Microsoft\MediaPlayer\Player\Settings (если такого раздела нет, то сформируйте его самостоятельно) создаем параметр с именем EnableDVDUI и параметром Yes.

Ну вот мы и поэкспериментировали немного с Windows XP. Конечно, это далеко не все, что можно делать с этой операционной системой с помощью реестра, но для начала хватит.