|
|
QA: How to copy registry key recursively?
By Andrey Yatsyk, April 30, 2002.
Print version
Question
How to copy registry key recursively with all subkeys and values?
Answer
Sometimes it is need to copy a registry key with all sub keys into other
place in registry. It can be useful when your program's setup changes some
standard registry key and you want that your program will restore changed
key after removing. Microsoft strictly recommends that your program should
be polite and restore registry state after uninstalling. Unfortunately there
is no way to copy a key with sub keys by one Win API function call and you should
write key traversing and coping code by hand.
I have written a function that does all dirty work for you and you should
just execute this function for deep registry copy. At first you should download
and add to your workspace RegUtil source and header files.
There is one function defined in that source code:
BOOL CopyRegistryKey(HKEY hkRootFrom, const CString& strFromPath,
HKEY hkRootTo, const CString& strToPath);
where hkRootFrom and hkRootTo are source and destination root
folders and strFromPath and strToPath are source and
destination paths.
Sources
Here is source code for the CopyRegistryKey function:
const static int nMaxValueNameSize = MAX_PATH;
const static int nMaxValueValueSize = 4096;
const static int nMaxClassSize = MAX_PATH;
const static int nMaxKeyNameSize = MAX_PATH;
static BOOL CopyKeys(HKEY hkFrom, HKEY hkTo)
{
TCHAR lpstrName[nMaxKeyNameSize];
TCHAR lpstrClass[nMaxClassSize];
for (int i = 0;;i++) {
DWORD nNameSize = nMaxKeyNameSize;
DWORD nClassSize = nMaxClassSize;
LONG res = ::RegEnumKeyEx(hkFrom, i, lpstrName, &nNameSize, 0,
lpstrClass, &nClassSize, 0);
if (ERROR_NO_MORE_ITEMS == res) {
break;
}
HKEY hkNew;
res = ::RegCreateKeyEx(hkTo, lpstrName, 0, lpstrClass,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hkNew, 0);
if (ERROR_SUCCESS != res) {
return FALSE;
}
::RegCloseKey(hkNew);
BOOL bRes = CopyRegistryKey(hkFrom, lpstrName, hkTo, lpstrName);
if (! bRes) {
return FALSE;
}
}
return TRUE;
}
static BOOL CopyValues(HKEY hkFrom, HKEY hkTo)
{
TCHAR lpstrName[nMaxValueNameSize];
BYTE pValue[nMaxValueValueSize];
for (int i = 0;;i++) {
DWORD nType;
DWORD nNameSize = nMaxValueNameSize;
DWORD nValueSize = nMaxValueValueSize;
LONG res = ::RegEnumValue(hkFrom, i, lpstrName, &nNameSize, 0,
&nType, pValue, &nValueSize);
if (ERROR_NO_MORE_ITEMS == res) {
break;
}
res = ::RegSetValueEx(hkTo, lpstrName, 0, nType, pValue, nValueSize);
if (ERROR_SUCCESS != res) {
return FALSE;
}
}
return TRUE;
}
BOOL CopyRegistryKey(HKEY hkRootFrom, const CString& strFromPath,
HKEY hkRootTo, const CString& strToPath)
{
HKEY hkFrom;
LONG res = ::RegOpenKeyEx(hkRootFrom, strFromPath, 0, KEY_READ, &hkFrom);
if (ERROR_SUCCESS != res) {
return FALSE;
}
HKEY hkTo;
res = ::RegCreateKeyEx(hkRootTo, strToPath, 0, 0, REG_OPTION_NON_VOLATILE,
KEY_WRITE, 0, &hkTo, 0);
if (ERROR_SUCCESS != res) {
::RegCloseKey(hkFrom);
return FALSE;
}
BOOL bRes = CopyKeys(hkFrom, hkTo) && CopyValues(hkFrom, hkTo);
::RegCloseKey(hkFrom);
::RegCloseKey(hkTo);
return bRes;
}
Related resources:
Discuss
Discuss this article.
Here you can write your comments and read comments of other developers.
|