WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

Registry UDFs

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

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
File Created: 2001:03:28:13:00:52
Last Updated: 2001:03:28:13:00:52