C++ C++ C# C# ASP.NET Security ASP.NET Security ASM ASM Скачать Скачать Поиск Поиск Хостинг Хостинг  
  Программа для работы с LPT портом...
Язык: .NET — ©Alexey...
  "ASP.NET Atlas" – AJAX в исполнении Micro...
Язык: .NET — ©legigor@mail.ru...
  "Невытесняющая" Многопоточность...
Язык: C/C++ — ©...
  01.05.2010 — Update World C++: Сборник GPL QT исходников
  15.12.2007 — Весь сайт целиком можно загрузить по ссылкам из раздела Скачать
Хостинг:
Windows 2003, ASP.NET 2.0
бесплатный и от 80 руб./мес


   Отправить письмо
Кулабухов Артем, Беларусь




 Как удалить ключ из реестра? / Реестр / Visual C++ .NET

Как удалить ключ из реестра?

Для удаления ключей из реестра предназначена функция RegDeleteKey из Win32 API. В качестве параметров эта функция получает дескриптор родительского ключа, а также имя подключа, подлежащего удалению. В качестве дескриптора родительского ключа можно передать константу, соответствующую одному из основных разделов реестра (HKEY_CLASSES_ROOT, HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER и т. п.), а также любой другой дескриптор, полученный в результате вызова функции RegOpenKey(Ex). В качестве примера рассмотрим код, удаляющий ключ "Some key" из раздела HKEY_LOCAL_MACHINE.
RegDeleteKey(HKEY_LOCAL_MACHINE, "Some key");
Функция RegDeleteKey удобна, но имеет один серьёзный недостаток: под Windows NT/2000 она удаляет из реестра только пустые ключи, то есть ключи, не содержащие подключей. Альтернативой RegDeleteKey является функция SHDeleteKey из shell API (объявлена в файле shlwapi.h). Она используется в точности так же, как и RegDeleteKey, например:
#include <shlwapi.h>
#pragma comment(lib,"shlwapi.lib")

...


SHDeleteKey(HKEY_LOCAL_MACHINE, "Some key");
Функция SHDeleteKey корректно удаляет непустые ключи из реестра как под Windows 9x, так и под Windows NT/2000, но, к сожалению, при её использовании возникает другая проблема: она появилась в библиотеке shlwapi.dll только начиная с версии 4.71. А это означает, что функция SHDeleteKey будет доступна под Windows 95 и Windows NT только при наличии Internet Explorer версии 4.0 и выше. Если прямое применение функций RegDeleteKey и SHDeleteKey не возможно, остаётся применить стандартный в таких случаях подход: написать свою функцию, которая будет удалять сначала все подключи некоторого ключа, я затем и сам ключ. Алгоритм работы этой функции может выглядеть примерно так: получаем список всех подключей заданного, рекурсивно вызываем для каждого из них нашу функцию удаления, а затем удаляем сам ключ при помощи RegDeleteKey. Вот один из возможных вариантов функции, рекурсивно удаляющей ключ вместе со всеми подключами.
LONG DeleteKey(HKEY hParentKey, LPCTSTR szKey)
{
    TCHAR *szSubKey = NULL;
    HKEY hKey = NULL;
    LONG nRes;

    __try
    {
        nRes = RegOpenKeyEx(hParentKey, szKey, 0, 
                            KEY_ENUMERATE_SUB_KEYS|KEY_READ | KEY_WRITE, &hKey);
        if(nRes != ERROR_SUCCESS)
            __leave;

        DWORD nMaxLen;
        RegQueryInfoKey(
            hKey, NULL, NULL, NULL, NULL,
            &nMaxLen, NULL, NULL, NULL, NULL, NULL, NULL);
        nMaxLen++;
        
        szSubKey = new TCHAR[nMaxLen];

        DWORD nSize = nMaxLen;
        FILETIME tTime;

        while((nRes=RegEnumKeyEx(
            hKey, 0, szSubKey, &nSize, 0, NULL, NULL, &tTime)) == ERROR_SUCCESS)
        {
            nRes = DeleteKey(hKey, szSubKey);
            if(nRes != ERROR_SUCCESS)
                __leave;

            nSize = nMaxLen;
        }

        nRes = RegDeleteKey(hParentKey, szKey);
    }
    __finally
    {
        if(szSubKey != NULL)
            delete [] szSubKey;

        if(hKey != NULL)
            RegCloseKey(hKey);

        return nRes;
    }
}
Если эта функция кажется вам слишком сложной, вам будет приятно узнать, что Microsoft уже написала её за вас. Соответствующая функция называется RecurseDeleteKey и является членом класса CRegKey из библиотеки ATL. Пример её использования приведён ниже.
#include <atlbase.h>

...

CRegKey rKey;
rKey.Attach(HKEY_LOCAL_MACHINE);
rKey.RecurseDeleteKey("Some key");
Хотя класс CRegKey входит в библиотеку ATL, он целиком реализован в заголовочном файле atlbase.h и не использует ссылается на другие классы ATL. Поэтому его использование не приведёт к "раздуванию" кода вашей программы. Следует, однако, иметь в виду, что в функции RecurseDeleteKey на имя подключа выделяется ровно 256 байт, что теоретически может привести к проблемам под Windows NT/2000, где длина имени ключа может быть и больше. Хотя на практике такие длинные ключи практически никогда не встречаются. Описанных способов оказывается вполне достаточно, чтобы решить поставленную задачу.