Сообщений 0 Оценка 275 Оценить |
Для копирования ключей в реестре предназначена функция 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"); |
Сообщений 0 Оценка 275 Оценить |