Sign in to follow this  
Followers 0
JMiller

Import Registry (Only tested on XP)

5 posts in this topic

This is a little utility I wrote awhile back and figured I might as well share in case anyone would find it useful.

The idea is simple... let's say you have some user-specific settings (i.e. in HKCU branch of the registry) that you want to apply to existing user profiles on a computer.

Maybe you made a configuration change to a program and want other users to have the new settings (without having to delete the profile and lose other settings/files they may have). You simply export the appropriate section of HKCU and use this program to apply it to the existing profiles.

;Include required files.
#include <GUIConstants.au3>

;Set script options.
Opt("TrayIconHide", 1)
Opt("GUIOnEventMode", 1)

;Ensure the required files are present.
$systemDrive = EnvGet("systemdrive")
$regExePath = @WindowsDir & "\system32\reg.exe"
$regeditExePath = @WindowsDir & "\regedit.exe"
If Not FileExists($regExePath) Or Not FileExists($regeditExePath) Then
    MsgBox(0, "Error", "Sorry, this program is only compatible with Windows XP.")
    Exit
EndIf

;Create GUI elements.
$mainWindow = GUICreate("Import Registry File", 400, 480, -1, -1, -1, $WS_EX_ACCEPTFILES)

;Create description area.
GUICtrlCreateGroup("Description", 10, 10, 380, 88)
GUICtrlCreateLabel("This program is designed to allow you to apply registry settings from an exported registry (.reg) file to existing user profiles on the computer.  Only files exported from the HKEY_CURRENT_USER section of the registry can be imported.  You must be a member of the Administrators group to access other profiles.  Profiles that are locked by the OS will be skipped.", 20, 25, 360, 72)

;Create options area.
GUICtrlCreateGroup("Options", 10, 108, 380, 120)
GUICtrlCreateLabel("Select the registry file to import.", 20, 125, 360, 20)

;Create Browse button to select the registry file.
$browseButton = GUICtrlCreateButton("Browse...", 20, 142, 70, 20)
GUICtrlSetOnEvent($browseButton, "browseClicked")
$regPathInput = GUICtrlCreateInput("", 100, 142, 280, 20)
GUICtrlSetState($regPathInput, $GUI_ACCEPTFILES)

;Create checkboxes to specify which profiles to update.
GUICtrlCreateLabel("Which profiles do you want to update?", 20, 167, 360, 20)
GUICtrlCreateLabel("Default User profile", 40, 185, 250, 20)
$defaultUser = GUICtrlCreateCheckbox("", 22, 185, 14, 14)
GUICtrlCreateLabel("Existing user profiles (besides Default User)", 40, 205, 250, 20)
$existingUsers = GUICtrlCreateCheckbox("", 22, 205, 14, 14)

;Create status area.
GUICtrlCreateGroup("Status", 10, 238, 380, 200)
$statusBox = GUICtrlCreateEdit("", 20, 255, 360, 173, BitOR($WS_HSCROLL, $WS_VSCROLL, $ES_MULTILINE, $ES_READONLY), 0)

;Create Action buttons section.
$updateButton = GUICtrlCreateButton("Update Registry", 85, 448, 110, 25)
GUICtrlSetOnEvent($updateButton, "updateClicked")
$closeButton = GUICtrlCreateButton("Close Program", 205, 448, 110, 25)
GUICtrlSetOnEvent($closeButton, "closeClicked")

;Set close event.
GUISetOnEvent($GUI_EVENT_CLOSE, "closeClicked")

;Build the GUI.
GUISetState(@SW_SHOW)
While 1
    Sleep(1000) ;Idle around
WEnd

Func browseClicked()
    ;Display a file open dialog box.
    $regFilePath = FileOpenDialog("Please select the registry file to import.", @ScriptDir & "\", "Registry Files (*.reg)", 1)
    GUICtrlSetData($regpathInput, $regFilePath)
EndFunc

Func updateClicked()
    ;Import the registry file into the specified profiles.
    $tempString = "temp"
    $tempFilePath = @ScriptDir & "\import_" & $tempString & ".reg"
    $tempKey = "HKU\" & $tempString
    $UNICODE_MODE = 32
    $error = 0
    $UNABLE_TO_OPEN = 1
    $UNABLE_TO_DELETE = 2
    $UNABLE_TO_UNLOAD = 3
    $hkcuFound = False
    
    If StringLen(GUICtrlRead($regPathInput)) <> 0 Then
        ;The string was at least 1 character long.
        If FileExists(GUICtrlRead($regPathInput)) Then
            ;The registry file was found.
            If GUICtrlRead($defaultUser) = $GUI_CHECKED Or GUICtrlRead($existingUsers) = $GUI_CHECKED Then
                ;At least one of the checkboxes was checked.  Start processing the registry file.
                
                ;Disable the action buttons while running.
                GUICtrlSetState($updateButton, $GUI_DISABLE)
                GUICtrlSetState($closeButton, $GUI_DISABLE)
                
                ;Begin writing the log to the status box.
                GUICtrlSetData($statusBox, "[" & @HOUR & ":" & @MIN & ":" & @SEC & "] Process started.")
                
                ;Delete the temporary file if it exists.
                If FileExists($tempFilePath) Then
                    FileDelete($tempFilePath)
                    If FileExists($tempFilePath) Then
                        ;The delete was unsuccessful. Write an error message to the status box.
                        $error = $UNABLE_TO_DELETE
                    Else
                        ;Open the temporary file for writing.
                        $tempFile = FileOpen($tempFilePath, 1)
                    EndIf
                Else
                    ;Open the temporary file for writing.
                    $tempFile = FileOpen($tempFilePath, 1)
                EndIf
                
                If $error = 0 Then
                    ;Open the original registry file for reading.
                    $origFile = FileOpen(GUICtrlRead($regPathInput), 0 + $UNICODE_MODE)
                    
                    ;Check if original registry file opened successfully.
                    If $origFile = -1 Then
                        MsgBox(0, "Error", "Unable to open registry file (" & $origFile & ").")
                        $error = $UNABLE_TO_OPEN
                    EndIf
                    
                    If $error = 0 Then
                        ;Write the boiler-plate line to the top of the temporary file.
                        FileWriteLine($tempFile, "Windows Registry Editor Version 5.00" & @CRLF)
                        
                        ;Read each line from the original registry file.
                        While 1
                            $line = FileReadLine($origFile)
                            If @error = -1 Then ExitLoop
                            If StringInStr($line, "Windows Registry Editor Version 5.00") Or StringInStr($line, "REGEDIT4") Then
                                ;Skip the line, because it is already accounted for.
                            Else
                                ;GUICtrlSetData($statusBox, GUICtrlRead($statusBox) & @CRLF & $line)
                                If StringInStr($line, "[HKEY_CURRENT_USER\") Then
                                    ;Modify the line, because it was exported from HKCU.
                                    $hkcuFound = True
                                    $line = StringReplace($line, "[HKEY_CURRENT_USER\", "[HKEY_USERS\" & $tempString & "\")
                                EndIf
                                If StringInStr($line, "[-HKEY_CURRENT_USER\") Then
                                    ;Modify the line, because it was exported from HKCU.
                                    $hkcuFound = True
                                    $line = StringReplace($line, "[-HKEY_CURRENT_USER\", "[-HKEY_USERS\" & $tempString & "\")
                                EndIf
                                FileWriteLine($tempFile, $line)
                            EndIf
                        Wend
                        
                        ;Close the original registry file.
                        FileClose($origFile)
                        
                        ;Close the temporary registry file.
                        FileClose($tempFile)
                        
                        If $hkcuFound = True Then
                            ;At least one entry referred to HKEY_CURRENT_USER. Proceed to importing the temporary registry file.
                            ;Check for the presence of the temporary hive and close it if needed.
                            SetError(0) ;Set the error to none to begin.
                            RegRead($tempKey, "")
                            If @error = 1 Then
                                ;The key did not exist, indicating that it is safe to proceed.
                                SetError(0) ;Set error back to none after testing.
                            Else
                                ;Attempt to close the key, because it shouldn't exist.
                                $command = $regExePath & " UNLOAD " & $tempKey
                                RunWait($command)
                                ;Check again for the presence of the key, to see if it was successfully removed.
                                SetError(0) ;Set the error to none to begin.
                                RegRead($tempKey, "")
                                If @error = 1 Then
                                    ;The key was successfully unloaded. Continue the process.
                                    SetError(0) ;Set error back to none after testing.
                                Else
                                    ;The key was not unloaded. Generate an error in the status box.
                                    $error = $UNABLE_TO_UNLOAD
                                    GUICtrlSetData($statusBox, GUICtrlRead($statusBox) & @CRLF & "Error: A hive was already mapped to the temporary key (" & $tempKey & ") and could not be unloaded.")
                                EndIf
                            EndIf
                            
                            If $error = 0 Then
                                ;There were no errors. Begin importing hives and merging the temporary registry file.
                                If GUICtrlRead($defaultUser) = $GUI_CHECKED And GUICtrlRead($existingUsers) = $GUI_UNCHECKED Then
                                    ;Only the default user profile should be updated.
                                    If FileExists($systemDrive & "\Documents and Settings\Default User\ntuser.dat") Then
                                        ;Attempt to load the ntuser.dat file into the registry.
                                        ;GUICtrlSetData($statusBox, GUICtrlRead($statusBox) & @CRLF & "Loading hive " & $systemDrive & "\Documents and Settings\Default User\ntuser.dat.")
                                        $command = $regExePath & " LOAD " & $tempKey & " """ & $systemDrive & "\Documents and Settings\Default User\ntuser.dat" & """"
                                        RunWait($command, "", @SW_HIDE)
                                        ;Ensure the loaded key exists.
                                        RegRead($tempKey, "")
                                        If @error <> -1 Then
                                            ;There was some kind of error, skip importing the file.
                                            GUICtrlSetData($statusBox, GUICtrlRead($statusBox) & @CRLF & "Notice: Unable to open " & $systemDrive & "\Documents and Settings\Default User\ntuser.dat.")
                                            SetError(0) ;Clear the error.
                                        Else
                                            ;Import registry settings.
                                            SetError(0) ;Set error back to none after testing.
                                            GUICtrlSetData($statusBox, GUICtrlRead($statusBox) & @CRLF & "Updating " & $systemDrive & "\Documents and Settings\Default User\ntuser.dat.")
                                            $command = $regeditExePath & " /s """ & $tempFilePath & """"
                                            RunWait($command, "", @SW_HIDE)
                                            ;Unload the registry hive.
                                            ;GUICtrlSetData($statusBox, GUICtrlRead($statusBox) & @CRLF & "Unloading hive " & $systemDrive & "\Documents and Settings\Default User\ntuser.dat.")
                                            $command = $regExePath & " UNLOAD " & $tempKey
                                            RunWait($command, "", @SW_HIDE)
                                            ;Ensure the hive was unloaded.
                                            RegRead($tempKey, "")
                                            If @error = 1 Then
                                                ;The hive was no longer present. Continue normally.
                                                SetError(0) ;Set the error back to none after testing.
                                            Else
                                                ;The hive was not unloaded as expected. Generate an error in the status box.
                                                GUICtrlSetData($statusBox, GUICtrlRead($statusBox) & @CRLF & "Error: Unable to unload " & $systemDrive & "\Documents and Settings\Default User\ntuser.dat.")
                                                $error = $UNABLE_TO_UNLOAD
                                            EndIf
                                        EndIf
                                    EndIf
                                Else
                                    ;Existing user profiles should be updated.
                                    $profileDir = $systemDrive & "\Documents and Settings"
                                    If FileExists($profileDir) Then
                                        ;The root profile path was present.
                                        If FileChangeDir($profileDir) Then
                                            ;Changed working directory to the root profile path.
                                            $search = FileFindFirstFile("*")
                                            If $search <> -1 Then
                                                ;At least one file or folder was found in the directory.
                                                $error = 0
                                                While $error = 0
                                                    $currentFile = FileFindNextFile($search)
                                                    If @error Then ExitLoop
                                                    If StringInStr(FileGetAttrib($currentFile), "D") Then
                                                        ;The current file is a directory.
                                                        If $currentFile = "All Users" Or $currentFile = "LocalService" Or $currentFile = "NetworkService" Then
                                                            ;Skip the folder, because is a system folder and should not be altered.
                                                        Else
                                                            ;See if the folder is for Default User, and if Default User should be updated.
                                                            If $currentFile <> "Default User" Or GUICtrlRead($defaultUser) = $GUI_CHECKED Then
                                                                ;Attempt to update the profile.
                                                                If FileExists($profileDir & "\" & $currentFile & "\ntuser.dat") Then
                                                                    ;Attempt to load the ntuser.dat file into the registry.
                                                                    $command = $regExePath & " LOAD " & $tempKey & " """ & $profileDir & "\" & $currentFile & "\ntuser.dat" & """"
                                                                    RunWait($command, "", @SW_HIDE)
                                                                    ;Ensure the loaded key exists.
                                                                    RegRead($tempKey, "")
                                                                    If @error <> -1 Then
                                                                        ;There was some kind of error, skip importing the file.
                                                                        GUICtrlSetData($statusBox, GUICtrlRead($statusBox) & @CRLF & "Notice: Unable to load " & $profileDir & "\" & $currentFile & "\ntuser.dat.")
                                                                        SetError(0) ;Clear the error.
                                                                    Else
                                                                        ;Import registry settings.
                                                                        SetError(0) ;Set error back to none after testing.
                                                                        GUICtrlSetData($statusBox, GUICtrlRead($statusBox) & @CRLF & "Updating " & $profileDir & "\" & $currentFile & "\ntuser.dat.")
                                                                        $command = $regeditExePath & " /s """ & $tempFilePath & """"
                                                                        RunWait($command, "", @SW_HIDE)
                                                                        ;Unload the registry hive.
                                                                        $command = $regExePath & " UNLOAD " & $tempKey
                                                                        RunWait($command, "", @SW_HIDE)
                                                                        ;Ensure the hive was unloaded.
                                                                        RegRead($tempKey, "")
                                                                        If @error = 1 Then
                                                                            ;The hive was no longer present. Continue normally.
                                                                            SetError(0) ;Set the error back to none after testing.
                                                                        Else
                                                                            ;The hive was not unloaded as expected. Generate an error in the status box.
                                                                            GUICtrlSetData($statusBox, GUICtrlRead($statusBox) & @CRLF & "Error: Unable to unload " & $profileDir & "\" & $currentFile & "\ntuser.dat.")
                                                                            $error = $UNABLE_TO_UNLOAD
                                                                        EndIf
                                                                    EndIf
                                                                Else
                                                                    ;The NTUSER.DAT registry file was not found.
                                                                    GUICtrlSetData($statusBox, GUICtrlRead($statusBox) & @CRLF & "Notice: Unable to find " & $profileDir & "\" & $currentFile & "\ntuser.dat.")
                                                                EndIf
                                                            EndIf
                                                        EndIf
                                                    EndIf
                                                WEnd
                                            Else
                                                ;No files or folders were found in the directory.
                                                GUICtrlSetData($statusBox, GUICtrlRead($statusBox) & @CRLF & "Error: No files or folders were found in " & $profileDir & ".")
                                            EndIf
                                        Else
                                            ;Unable to change the working directory.
                                            GUICtrlSetData($statusBox, GUICtrlRead($statusBox) & @CRLF & "Error: Unable to set working directory to " & $profileDir & ".")
                                        EndIf
                                    Else
                                        ;Unable to find profile path.
                                        GUICtrlSetData($statusBox, GUICtrlRead($statusBox) & @CRLF & "Error: Unable to find " & $profileDir & ".")
                                    EndIf
                                EndIf
                            EndIf
                        Else
                            ;No sections in the registry file pointed to HKEY_CURRENT_USER. Generate an error in the status box.
                            GUICtrlSetData($statusBox, GUICtrlRead($statusBox) & @CRLF & "Error: Stopping process because the registry file (" & GUICtrlRead($regPathInput) & ") did not contain any entries from HKEY_CURRENT_USER.")
                        EndIf
                        
                    Else
                        ;Write the error to the status box.
                        GUICtrlSetData($statusBox, GUICtrlRead($statusBox) & @CRLF & "Error: Stopping process because the registry file (" & GUICtrlRead($regPathInput) & ") could not be opened.")
                    EndIf
                    
                    ;Delete the temporary file.
                    FileDelete($tempFilePath)
                Else
                    ;Write the error to the statux box.
                    GUICtrlSetData($statusBox, GUICtrlRead($statusBox) & @CRLF & "Error: Stopping process because the temporary file (" & $tempFilePath & ") could not be deleted. Please ensure that you have the appropriate permissions.")
                EndIf
                
                ;Add a final entry to the status box indicating process completion.
                GUICtrlSetData($statusBox, GUICtrlRead($statusBox) & @CRLF & "[" & @HOUR & ":" & @MIN & ":" & @SEC & "] Process completed. Check above for errors.")
                
                ;Re-enable the action buttons.
                GUICtrlSetState($updateButton, $GUI_ENABLE)
                GUICtrlSetState($closeButton, $GUI_ENABLE)
            Else
                ;Neither checkbox was checked.
                MsgBox(0, "Error", "Please select which profiles you want to update. At least one box must be checked.")
            EndIf
        Else
            ;The registry file was not found.
            MsgBox(0, "Error", "The registry file (" & GUICtrlRead($regPathInput) & ") was not found.")
        EndIf
    Else
        ;The registry file path was empty.
        MsgBox(0, "Error", "You must specify the registry file to import.")
    EndIf
EndFunc

Func closeClicked()
    ;Exit the script.
    Exit
EndFunc

importRegistry.exe

post-12659-1204586810_thumb.gif

Share this post


Link to post
Share on other sites



This could be very useful for me, but I'm trying to follow the code and am getting a little confused in how this works. Does it essentially create an export of each users hive, merge the .reg file, and then re-import? I'm confused, please clarify. Thanks!

Share this post


Link to post
Share on other sites

This could be very useful for me, but I'm trying to follow the code and am getting a little confused in how this works. Does it essentially create an export of each users hive, merge the .reg file, and then re-import? I'm confused, please clarify. Thanks!

Oh, sorry for the untimely reply. I thought I had e-mail notification turned on. Basically what it does is this:

Takes the specified .reg file and creates a new temporary file. The temporary file contents are the same, except where [HKEY_CURRENT_USER\ is encountered, in which case it changes that to [HKEY_USERS\temp\. Whenever you export user-level settings from the registry, it's from HKEY_CURRENT_USER. (It also replaces [-HKEY_CURRENT_USER\ to [-HKEY_USERS\temp\ in the event that you want automate key deletion with the .reg file. Maybe you want to purge a key before writing the values back to it, so you know exactly what's in it.)

So the new file references [HKEY_USERS\temp instead, which is where the program will be temporarily loading user profiles to in the registry.

After the temporary .reg file has been created with the correct paths, the script loops through each user profile and uses the REG LOAD command to load the profile (ntuser.dat) to HKEY_USERS\temp. Then, when the profile is loaded, it uses the regedit.exe command to merge the temporary .reg file into the user profile. Finally, it unloads the user's profile and proceeds to the next one.

So, to answer your question, it doesn't export the user's hive. It actually just temporarily loads the hive to a specific location in the registry and merges a modified .reg file that references that same location.

Hope this explanation helps!

Share this post


Link to post
Share on other sites

can't download attached file. pls help

Share this post


Link to post
Share on other sites

trexln,

Welcome to the AutoIt forum. :)

But be reasonable, the OP has not been online since Mar 2008 - do you really think he is going to reply after nearly 5 years? :huh:

Please do not necro-post like this again. ;)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0