Clone and Rename Registry Trees
Keywords: RegQueryValue RegOpen
;This set of UDFs can clone or rename a registry key
;It is not blindingly fast, but should be ok for smaller trees.
;
;CopyRegValue - Copies one single value from one place to another
;
;CloneRegTree - copies one tree from one place to another
;
;RenameRegTree - Renames a tree.
;
;However, due to the fact that the registry API does not have
;a rename facility, the RenameRegTreeis implemented by first
;cloning the tree, then deleting the original tree.
;
;Keys are used by first obtaining a handle to one. One of the
;predefined handles (@REGMACHINE @REGCURRENT, etc) or a handle
;returned by one of the registry functions RegConnect, RegCreateKey
;or RegOpenKey may be used
;Each function needs a handle to a section in the registry
;database in addition to a string that consists of the subkey to
;an entry in the Registry database.
;
;For current versions of Windows, there are 4 handles: @REGMACHINE,
;@REGCLASSES, @REGUSRS, and @REGCURRENT. These are WIL constants
;for HKEY_LOCAL_MACHINE, HKEY_CLASSES_ROOT, HKEY_USERS, and
;HKEY_CURRENT_USER. When you obtain a registry subkey from Microsoft's
;registry viewer, regedit.exe (by using Copy Key Name from the right
;mouse menu in RegEdit.exe) it will look like this example:
;HKEY_LOCAL_MACHINE\SOFTWARE\myTest\Sub2\sub21\Sub211
;
;For use in the WIL registry functions, the above key must be
;divided into handle and subkey. The handle, @REGMACHINE, takes the
;place of the first item, 'HKEY_LOCAL_MACHINE\'. The subkey needed
;for the second parameter in the functions is, 'SOFTWARE\myTest\Sub2\sub21\Sub211'.
;Note: it does not start with the '\' backslash character.
;Note: By using the key handles returned by the RegConnect function, a copy
;of a tree on one machine by be cloned to the registry of a different machine
; 20010321, mmw - Original version
; 20010328, jwt - Added, capability to copy reg from server to server.
; 20010328, jwt - Added, code will now skip unwritable values and log to ini.
; 20010328, jwt - Changed, Query regtype on default values, was bombing on non string values.
; 20010328, jwt - Added, detect type 7 values (Multi_Sz) and set delimiter to tab.
; 20010328, jwt - Added, Using shell extender to display some progress to the user. Still don't think I have
; the status bars in the right place, but its functional.
; 20010328, mmw - Deleted above status bar change, kept rest of changes
; 20010328, mmw - Standardized on a TAB delim character. What was I thinking?
;==========================================================================================================
;Define the CopyRegValue UDF.
#DefineFunction CopyRegValue(fromHandle,fromSubkey,toHandle,toSubkey)
;Stop if value does not exist.
Terminate(RegExistValue(fromHandle,fromSubkey)==0,"Reg value does not exist",fromSubkey)
type=RegEntryType(fromHandle,fromSubkey) ;Get the entry type
; (jwt) just skip unwritable values, log values for later review.
If ((type<1) || (type>4)) && type!=7
IniWritePvt("Errors",fromSubkey,"Type %type% values cannot be processed","WWWERRLOG.INI")
Return
Endif
value=RegQueryEx(fromHandle,fromSubkey,@TAB,type) ;Get the value.
RegSetEx(toHandle,toSubkey,value,@TAB,type)
return ;Return nothing.
#endfunction
;==========================================================================================================
;Define the CloneRegTree udf.
#DefineFunction CloneRegTree(fromHandle, fromSubkey, toHandle, toSubkey)
;Stop if key does not exist.
Terminate(RegExistKey(fromHandle,fromSubkey)==0,"Reg key does not exist",fromSubkey)
;copy top default key
if RegExistValue(fromhandle,fromsubkey) ;Check value.
; (jwt) old code was bombing out on binary values.
type=RegEntryType(fromHandle,fromSubkey)
; (jwt) add code to change Multi_Sz delim to tab.
defval=RegQueryEx(fromHandle,fromSubkey,@tab,type)
if defval!="" then RegSetEx(toHandle,toSubkey,defval,@tab,type)
endif
;copy all values under key, if any
items=RegQueryItem(fromHandle,fromSubkey)
icount=ItemCount(items,@tab)
for ii=1 to icount
thisitem=strcat(fromSubkey,'[',ItemExtract(ii,items,@tab),']') ; Assemble source subkey with value in brackets.
thatitem=strcat(toSubkey,'[',ItemExtract(ii,items,@tab),']') ; Assemble destination subkey with value in brackets.
CopyRegValue(fromHandle, thisitem, toHandle, thatitem) ; Copy the entry.
next
;Get list of subkeys
tempkey=RegOpenKeyEX(fromHandle,fromSubkey,"READ",0,0) ; Open source key with read access rights.
keys=RegQueryKeys(tempkey) ; Get keys.
RegCloseKey(tempkey) ; Close source key.
;Process each subkey
kcount=ItemCount(keys,@tab)
for kk=1 to kcount
thiskey=strcat(fromSubkey,"\",ItemExtract(kk,keys,@tab))
thatkey=strcat(toSubkey,"\",ItemExtract(kk,keys,@tab))
CloneRegTree(fromHandle,thiskey,toHandle,thatkey) ; Use the CloneRegTree UDF to do the work.
next
#EndFunction
;==========================================================================================================
#DefineFunction RenameRegTree(fromHandle, fromSubkey, toHandle, toSubkey) ; Set up UDF
CloneRegTree(fromHandle, fromSubkey, toHandle, toSubkey) ; Use previous UDF to copy the source key to the destination key.
RegDeleteKey(fromHandle,fromSubkey) ; Delete the source key.
#EndFunction
;==========================================================================================================
;==========================================================================================================
;==========================================================================================================
;==========================================================================================================
;==========================================================================================================
;Test code follows.
fromHandle = @REGCURRENT ; Registry handle. In this case, both source and destination are the same.
toHandle = @REGCURRENT
fromSubkey = "Software\Wilson WindowWare" ;source subkey
toSubkey = "Software\MyWilson WindowWare" ;destination subkey
CloneRegTree( fromHandle , fromSubkey , toHandle , toSubkey) ; copy the subkey
Message("Progress" , "New key created.%@CRLF%%@CRLF%See this with regedit.exe, %@CRLF%Be sure to refresh it with f5!")
fromSubkey = "Software\MyWilson WindowWare"
toSubkey = "Software\MyOtherWilson WindowWare"
RenameRegTree( fromHandle , fromSubkey , toHandle , toSubkey) ;copy the subkey to a new named key, and delete the old key.
Message("Progress" , "New key copied and renamed.%@CRLF%%@CRLF%Check this with f5 in regedit.exe.")
Article ID: W14745
Filename: Clone and Rename Registry Trees.txt