JMiller Posted March 3, 2008 Share Posted March 3, 2008 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. expandcollapse popup;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 EndFuncimportRegistry.exe Link to comment Share on other sites More sharing options...
skewltek Posted March 5, 2008 Share Posted March 5, 2008 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! Link to comment Share on other sites More sharing options...
JMiller Posted March 23, 2008 Author Share Posted March 23, 2008 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! Link to comment Share on other sites More sharing options...
trexln Posted November 14, 2013 Share Posted November 14, 2013 can't download attached file. pls help Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted November 14, 2013 Moderators Share Posted November 14, 2013 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? 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 Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now