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

Как скопировать ключ в реестре?

Для копирования ключей в реестре предназначена функция SHCopyKey (объявлена в shlwapi.h). Она имеет следующий прототип.
DWORD SHCopyKey(
    HKEY hkeySrc,
    LPCTSTR szSrcSubKey,
    HKEY hkeyDest,
    DWORD fReserved
);
В качестве первого параметра функция получает дескриптор исходного ключа, второй параметр содержит имя подключа, подлежащего копированию, третий - дескриптор целевого ключа, а четвёртый параметр зарезервирован и должен быть равен NULL. Рассмотрим пример копирования ключа "Some key" из раздела HKEY_LOCAL_MACHINE в раздел HKEY_CURRENT_USER.
#include <shlwapi.h>
#pragma comment(lib,"shlwapi.lib")

...

SHCopyKey(HKEY_LOCAL_MACHINE, "Some key", HKEY_CURRENT_USER, NULL);
К сожалению, функция SHCopyKey имеет два серьёзных недостатка. Во-первых, она входит в библиотеку shlwapi.dll только начиная с версии 5.0, а значит, эта функция доступна только под Windows 2000 или при наличии Internet Explorer версии 5.0 и выше. Во-вторых, при копировании ключа ему нельзя задать другое имя. Это исключает применение функции SHCopyKey для переименования ключей в реестре. Для решения указанных проблем придётся писать собственную функцию, выполняющую копирование ключей. Алгоритм её работы может быть таким: открываем исходный ключ, строим список всех его подключей, рекурсивно вызываем для каждого подключа функцию копирования, а затем строим список всех параметров, содержащихся в ключе, и копируем каждый из них на новое место. Вот одна из возможных реализаций этого алгоритма.
LONG CopyKey(HKEY hSrcParent, HKEY hTargParent, LPCTSTR szSrcKey, LPCTSTR szTargKey)
{
    LONG nRes;
    TCHAR *szSubKeyName = NULL;
    TCHAR *szValueName = NULL;
    BYTE *pData = NULL;
    HKEY hSrcKey = NULL, hTargKey = NULL;
    
    __try
    {
        nRes = RegCreateKey(hTargParent, szTargKey, &hTargKey);
        if(nRes != ERROR_SUCCESS)
            __leave;

        nRes = RegOpenKeyEx(hSrcParent, szSrcKey, 0, KEY_ENUMERATE_SUB_KEYS | KEY_READ, &hSrcKey);
        if(nRes != ERROR_SUCCESS)
            __leave;

        DWORD nMaxKeyNameLen, nMaxValueNameLen, nMaxValueLen;
        RegQueryInfoKey(
            hSrcKey, NULL, NULL, NULL, NULL,
            &nMaxKeyNameLen, NULL, NULL,
            &nMaxValueNameLen, &nMaxValueLen, NULL, NULL);

        nMaxKeyNameLen++;
        nMaxValueNameLen++;

        szSubKeyName = new TCHAR[nMaxKeyNameLen];
        DWORD nIndex = 0, nSize = nMaxKeyNameLen;
        FILETIME tTime;

        while(RegEnumKeyEx(
            hSrcKey, nIndex++, szSubKeyName, &nSize, 0, NULL, NULL, &tTime) == ERROR_SUCCESS)
        {
            LONG nRes = CopyKey(hSrcKey, hTargKey, szSubKeyName, szSubKeyName);
            if(nRes != ERROR_SUCCESS)
                __leave;

            nSize = nMaxKeyNameLen;
        }

        szValueName = new TCHAR[nMaxValueNameLen];
        pData = new BYTE[nMaxValueLen];
        DWORD nType, nDataSize;

        nIndex = 0;
        nSize = nMaxValueNameLen;
        nDataSize = nMaxValueLen;

        while(RegEnumValue(
            hSrcKey, nIndex++, szValueName, &nSize,
            NULL, NULL, pData, &nDataSize) == ERROR_SUCCESS)
        {
            nRes = RegQueryValueEx(hSrcKey, szValueName, NULL, &nType, pData, &nDataSize);
            if(nRes != ERROR_SUCCESS)
                __leave;

            nRes = RegSetValueEx(hTargKey, szValueName, NULL, nType, pData, nDataSize);
            if(nRes != ERROR_SUCCESS)
                __leave;

            nSize = nMaxValueNameLen;
            nDataSize = nMaxValueLen;
        }

        nRes = ERROR_SUCCESS;
    }
    __finally
    {
        if(szSubKeyName != NULL)
            delete [] szSubKeyName;

        if(szValueName != NULL)
            delete [] szValueName;

        if(pData != NULL)
            delete [] pData;

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

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

        return nRes;
    }
}
Параметры функции CopyKey аналогичны параметрам SHCopyKey. Обратите внимание, что дополнительный параметр szTargKey позволяет изменить имя исходного ключа при копировании. Вот пример копирования ключа "Some key" из раздела HKEY_LOCAL_MACHINE в раздел HKEY_CURRENT_USER с использованием CopyKey.
CopyKey(HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER, "Some key", "Some key");