Оценка 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"); |
Оценка 275 Оценить ![]() ![]() ![]() ![]() ![]() ![]()
|