Sign in to follow this  
Followers 0
usera

Reg.exe function

18 posts in this topic

Greeting,

How can I code to make the result as reg.exe does

REG EXPORT KeyName FileName [/y]

Keyname ROOTKEY[\SubKey] (local machine only).

ROOTKEY [ HKLM | HKCU | HKCR | HKU | HKCC ]

SubKey The full name of a registry key under the selected ROOTKEY.

FileName The name of the disk file to export.

/y Force overwriting the existing file without prompt.

Examples:

REG EXPORT HKLM\Software\MyCo\MyApp AppBkUp.reg

Exports all subkeys and values of the key MyApp to the file AppBkUp.reg

-----------------------------------------------------------------------------------------------

REG RESTORE KeyName FileName

KeyName ROOTKEY\SubKey (local machine only)

ROOTKEY [ HKLM | HKCU | HKCR | HKU | HKCC ]

SubKey The full name of a registry key to restore the hive file into.

Overwrites the existing key's values and subkeys.

FileName The name of the hive file to restore.

You must use REG SAVE to create this file.

Examples:

REG RESTORE HKLM\Software\Microsoft\ResKit NTRKBkUp.hiv

Restores the file NTRKBkUp.hiv overwriting the key ResKit

just dump the whole key to a file, then restore from a file

Thanks

usera

Share this post


Link to post
Share on other sites



How can I code to make the result as reg.exe does

RegEnumKey()

RegEnumVal()

RegRead()

RegWrite()

Read the help file, and look at the example code.

Share this post


Link to post
Share on other sites

RegEnumKey()

RegEnumVal()

RegRead()

RegWrite()

Read the help file, and look at the example code.

Thanks for your quick feedback.

But there is no one function to help me to get the function as below. the result is goto file "h:\OutlookSettings\Outlook.Bin"

reg.exe EXPORT "HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook" "h:\OutlookSettings\Outlook.Bin"

thanks

usera

Share this post


Link to post
Share on other sites

But there is no one function to help me to get the function as below. the result is goto file "h:\OutlookSettings\Outlook.Bin"

How about Run() or RunWait()?

If you want me to write a function for you, I charge $120/hour with a 1 hour minimum. :graduated:

Share this post


Link to post
Share on other sites

How about Run() or RunWait()?

If you want me to write a function for you, I charge $120/hour with a 1 hour minimum. :graduated:

Thanks for your offer, the reason ask for this, is the group policy block to run reg or regedit

usera

Share this post


Link to post
Share on other sites

Look here or here

Thanks for your help.

But... it is too hard for me to understand that.

usera

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

~

Edited by Mobius

Share this post


Link to post
Share on other sites

Your requirement was an export:

reg.exe EXPORT "HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook" "h:\OutlookSettings\Outlook.Bin"

If you download this UDF and name it _RegFunc.au3, then all you have to do is run this script to get the same result:

#include<_RegFunc.au3>

_RegExport('h:\OutlookSettings\Outlook.Bin', 'HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook')

Share this post


Link to post
Share on other sites

Your requirement was an export:

reg.exe EXPORT "HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook" "h:\OutlookSettings\Outlook.Bin"

If you download this UDF and name it _RegFunc.au3, then all you have to do is run this script to get the same result:

#include<_RegFunc.au3>

_RegExport('h:\OutlookSettings\Outlook.Bin', 'HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook')

Thank you VERY VERY much! it works, will test in the real environment and let you know

Share this post


Link to post
Share on other sites

Your requirement was an export:

reg.exe EXPORT "HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook" "h:\OutlookSettings\Outlook.Bin"

If you download this UDF and name it _RegFunc.au3, then all you have to do is run this script to get the same result:

#include<_RegFunc.au3>

_RegExport('h:\OutlookSettings\Outlook.Bin', 'HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook')

Thanks, but how about restore function then

like:

reg.exe Restore "HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook" "h:\OutlookSettings\Outlook.Bin"

usera

Share this post


Link to post
Share on other sites

Thanks, but how about restore function then

like:

reg.exe Restore "HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook" "h:\OutlookSettings\Outlook.Bin"

usera

Can anyone give a help?

usera

Share this post


Link to post
Share on other sites

The example Varian gave you for the export, the RegFunc UDF, and a very little effort looking at the code should get you there.

Share this post


Link to post
Share on other sites

Because there is no UDF that I can find that directly imports regfiles, I suggest that you export the regfile via the _RegFunc UDF, then find a registry converter UDF here on the forum. Then you can execute the script which will restore the registry to your desired result without ever using reg.exe or regedit

Share this post


Link to post
Share on other sites

The example Varian gave you for the export, the RegFunc UDF, and a very little effort looking at the code should get you there.

Thanks for your advise. Just not very good at that part and kind of rush to get that function.

Again Thanks

usera

Share this post


Link to post
Share on other sites

Because there is no UDF that I can find that directly imports regfiles, I suggest that you export the regfile via the _RegFunc UDF, then find a registry converter UDF here on the forum. Then you can execute the script which will restore the registry to your desired result without ever using reg.exe or regedit

Thanks Varian,

Could you please point me where is the registry converter UDF?

Thanks

usera

Share this post


Link to post
Share on other sites

I have combined the UDFs into 1 script for you. Lines 38-41 are the relevant ones (the area you need to modify to suit your needs) This script exports a regfile, converts that regfile to AutoIT with regwrites, and then deletes the regfile if the conversion is successful. You are left with 1 AutoIT script which if executed updates the registry with the settings from an exported regfile bypassing reg.exe

#include-once
#include <Constants.au3>
#include <File.au3>
#include <WindowsConstants.au3>
; ===============================================================================================================================
; Title:    _RegFunc
; Author:   Erik Pilsits
; Version:  2.0.1
; ===============================================================================================================================

;~ Global Const $ReG_NoNE = 0
;~ Global Const $REG_SZ = 1
;~ Global Const $REG_EXPAND_SZ = 2
;~ Global Const $REG_BINARY = 3
;~ Global Const $REG_DWORD = 4
;~ Global Const $REG_MULTI_SZ = 7
Global $Temp_Dir, $Temp_reg, $Name, $Path, $Reg1, $Reg2, $AU3, $Error = 0, $Key, $n
Global Const $REG_QWORD = 11
Global Const $HKEY_CLASSES_ROOT = 0x80000000
Global Const $HKEY_CURRENT_USER = 0x80000001
Global Const $HKEY_LOCAL_MACHINE = 0x80000002
Global Const $HKEY_USERS = 0x80000003
Global Const $HKEY_PERFORMANCE_DATA = 0x80000004
Global Const $HKEY_PERFORMANCE_TEXT = 0x80000050
Global Const $HKEY_PERFORMANCE_NLSTEXT = 0x80000060
Global Const $HKEY_CURRENT_CONFIG = 0x80000005
Global Const $HKEY_DYN_DATA = 0x80000006
Global Const $KEY_QUERY_VALUE = 0x0001
Global Const $KEY_SET_VALUE = 0x0002
Global Const $KEY_ENUMERATE_SUB_KEYS = 0x0008
Global Const $KEY_WRITE = 0x20006
Global Const $KEY_READ = 0x20019
Global Const $REG_OPTION_NON_VOLATILE = 0x0000
Global Const $REG_OPTION_VOLATILE = 0x0001
Global Const $KEY_WOW64_64KEY = 0x0100
Global Const $KEY_WOW64_32KEY = 0x0200

$OutputFile = @DesktopDir & '\Outlook.reg'
_RegExport($OutputFile, 'HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook')
_ConvertReg($OutputFile)
If Not @error Then FileRecycle($OutputFile)

#cs
    x64 Platforms:
    
    For all registry functions, the root key may be suffixed with either 32 or 64 to specify the
    particular registry view on which to operate.
    
    For example, HKLM32 will unconditionally reference the 32-bit registry view, while HKLM64 will
    unconditionally reference the 64-bit registry view.
    
    Examples:
    HKEY_LOCAL_MACHINE32
    HKEY_CURRENT_USER64
    HKU32
#ce

; #FUNCTION# ====================================================================================================
; Name...........:  _RegRead
; Description....:  Read a registry value.
; Syntax.........:  _RegRead($szKey, $szValue)
; Parameters.....:  $szKey      - Source key
;                   $szValue    - Source value (Empty string for Default value)
;
; Return values..:  Success - Requested data and value type in @extended
;                           | REG_MULTI_SZ, REG_BINARY, and REG_NONE are returned as binary data
;                           | REG_MULTI_SZ is returned as NULL separated substrings with 2 terminating NULLs
;                   Failure - 0 and sets @error
;                           | 1 - Invalid root key
;                           | 2 - Failed to open source key (@extended contains RegOpenKeyExW return value)
;                           | 3 - Unsupported value type
;                           | 4 - Failed to read source value (@extended contains RegQueryValueExW return value)
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegRead($szKey, $szValue)
    Local $hKey = _RegOpenKey($szKey, $KEY_READ)
    If @error Then Return SetError(@error, @extended, 0)
    Local $ret = DllCall("advapi32.dll", "long", "RegQueryValueExW", "ulong_ptr", $hKey, "wstr", $szValue, "ptr", 0, "dword*", 0, "ptr", 0, "dword*", 0)
    If @error Or ($ret[0] <> 0) Then
        DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey)
        If IsArray($ret) Then
            Return SetError(3, $ret[0], 0)
        Else
            Return SetError(3, 0, 0)
        EndIf
    EndIf

    Local $iType = $ret[4], $iLen = $ret[6], $sType
    Switch $iType ; set type of value
        Case $REG_SZ, $REG_EXPAND_SZ
            $sType = "wchar"
            ; iLen is byte length, if unicode string divide by 2
            ; add terminating null for possibly incorrectly stored strings
            ; handling of extra terminating NULLs is automatic by AutoIt 'wchar' type
            $iLen = ($iLen / 2) + 1
        Case $REG_MULTI_SZ
            ; multiple string value, returned as binary data
            ; iLen is byte length
            ; returns binary data, post handling is necessary
            $sType = "byte"
        Case $REG_BINARY, $REG_NONE
            $sType = "byte"
        Case $REG_QWORD
            $sType = "int64"
            $iLen = $iLen / 8 ; int64 = 8 bytes
        Case $REG_DWORD
            $sType = "dword"
            $iLen = $iLen / 4 ; dword = 4 bytes
        Case 5, 6, 8, 9, 10
            ; other uncommon value types, return as binary data
            $sType = "byte"
        Case Else
            ; unknown type
            DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey)
            Return SetError(3, 0, 0)
    EndSwitch
    Local $lpData = DllStructCreate($sType & "[" & $iLen & "]")
    $ret = DllCall("advapi32.dll", "long", "RegQueryValueExW", "ulong_ptr", $hKey, "wstr", $szValue, "ptr", 0, "dword*", 0, _
            "ptr", DllStructGetPtr($lpData), "dword*", DllStructGetSize($lpData))
    DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey)
    If (Not IsArray($ret)) Or ($ret[0] <> 0) Then
        If IsArray($ret) Then
            Return SetError(4, $ret[0], 0)
        Else
            Return SetError(4, 0, 0)
        EndIf
    EndIf
    Local $data
    ; special processing for REG_MULTI_SZ
    If $iType = $REG_MULTI_SZ Then
        ; trim all terminating NULLs and add the proper 2 terminating NULLs
        ; if no data, then return empty binary variant
        $data = _RegTrimBinary(DllStructGetData($lpData, 1), Binary("0x0000"))
        If $data Then $data &= Binary("0x00000000")
    Else
        ; else just get our data
        $data = DllStructGetData($lpData, 1)
    EndIf
    Return SetError(0, $iType, $data)
EndFunc   ;==>_RegRead

Func _RegTrimBinary($data, $pattern)
    ; trim a repeating binary pattern from the end of binary data
    ; set starting point to pattern byte size from end (BinaryMid is 1-based, so decrement 1 byte less than pattern length)
    Local $pLen = BinaryLen($pattern)
    Local $start = BinaryLen($data) - ($pLen - 1)
    While 1
        If $start < 0 Then
            ; if start is < 0, then there is no data left
            ; set start to 0 (returns empty binary variant from BinaryMid) and exit loop
            $start = 0
            ExitLoop
        EndIf
        ; test if a terminating null and decrement
        If BinaryMid($data, $start, $pLen) = $pattern Then
            $start -= $pLen
        Else
            ; found data, increment one byte
            $start += ($pLen - 1)
            ExitLoop
        EndIf
    WEnd
    ; get data
    Return BinaryMid($data, 1, $start)
EndFunc   ;==>_RegTrimBinary

; #FUNCTION# ====================================================================================================
; Name...........:  _RegWrite
; Description....:  Create a registry key or value.
; Syntax.........:  _RegWrite($szKey[, $szValue = ""[, $iType = -1[, $bData = Default[, $dwOptions = $REG_OPTION_NON_VOLATILE]]]])
; Parameters.....:  $szKey      - Destination key
;                   $szValue    - [Optional] Destination value (Empty string for Default value, must also supply $iType and $bData)
;                   $iType      - [Optional] Type of data to write to $szValue ($iType < 0 writes key only)
;                   $bData      - [Optional] Data to write to $szValue ($bData = Default creates key only)
;                   $dwOptions  - [Optional] Optional flags (can be $REG_OPTION_NON_VOLATILE or $REG_OPTION_VOLATILE)
;
; Return values..:  Success - 1
;                   Failure - 0 and sets @error
;                           | 1 - Invalid root key
;                           | 2 - Failed to open / create destination key (@extended contains RegCreateKeyExW return value)
;                           | 3 - Unsupported value type
;                           | 4 - Failed to write data (@extended contains RegSetValueExW return value)
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:  Provide REG_MULTI_SZ values as a single string made up of NULL separated substrings.
;                   Terminating NULLs for all string data types are correctly appended by the function.
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegWrite($szKey, $szValue = "", $iType = -1, $bData = Default, $dwOptions = $REG_OPTION_NON_VOLATILE)
    Local $hKey = _RegOpenKey($szKey, $KEY_WRITE, False, $dwOptions) ; open using RegCreateKeyExW
    If @error Then Return SetError(@error, @extended, 0)
    Local $lpData
    If $iType >= 0 And $bData <> Default Then
        Switch $iType
            ; handle strings as binary data, make sure they are properly terminated
            Case $REG_SZ, $REG_EXPAND_SZ
                $bData = StringToBinary($bData, 2) ; UTF16LE
                $bData = _RegTrimBinary($bData, "0x0000") & Binary("0x0000") ; add terminating null
                $lpData = DllStructCreate("byte[" & BinaryLen($bData) & "]")
            Case $REG_MULTI_SZ
                $bData = StringToBinary($bData, 2) ; UTF16LE
                $bData = _RegTrimBinary($bData, "0x0000") & Binary("0x00000000") ; add 2 terminating nulls
                $lpData = DllStructCreate("byte[" & BinaryLen($bData) & "]")
            Case $REG_DWORD
                $lpData = DllStructCreate("dword")
            Case $REG_QWORD
                $lpData = DllStructCreate("int64")
            Case $REG_BINARY, $REG_NONE
                $lpData = DllStructCreate("byte[" & BinaryLen($bData) & "]")
            Case 5, 6, 8, 9, 10
                ; other uncommon value types
                $lpData = DllStructCreate("byte[" & BinaryLen($bData) & "]")
            Case Else
                DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey)
                Return SetError(3, 0, 0)
        EndSwitch
        DllStructSetData($lpData, 1, $bData)
        Local $ret = DllCall("advapi32.dll", "long", "RegSetValueExW", "ulong_ptr", $hKey, "wstr", $szValue, "dword", 0, "dword", $iType, _
                "ptr", DllStructGetPtr($lpData), "dword", DllStructGetSize($lpData))
        If @error Or ($ret[0] <> 0) Then
            If IsArray($ret) Then
                Return SetError(4, $ret[0], 0)
            Else
                Return SetError(4, 0, 0)
            EndIf
        EndIf
    EndIf
    DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey)
    Return SetError(0, 0, 1)
EndFunc   ;==>_RegWrite

; #FUNCTION# ====================================================================================================
; Name...........:  _RegDelete
; Description....:  Delete a key (recursively) or value
; Syntax.........:  _RegDelete($szKey[, $szValue = Default])
; Parameters.....:  $szKey      - Key to delete
;                   $szValue    - [Optional] Value to delete (Default to recursively delete the key)
;
; Return values..:  Success - 1
;                   Failure - 0 and sets @error
;                           |-2 - Cannot delete a root key
;                           |-1 - Target key / value does not exist
;                           | 1 - Invalid root key
;                           | 2 - Failed to open subkey (@extended contains RegOpenKeyExW return value)
;                           | 3 - Failed to delete key / value (@extended contains RegDelete* return value)
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegDelete($szKey, $szValue = Default)
    If $szValue = Default Then
        If Not _RegKeyExists($szKey) Then Return SetError(-1, 0, 0)
        ; recursively delete keys
        Local $key
        While 1
            $key = _RegEnumKey($szKey, 0) ; removing keys, so always enum index 0
            If @error Then ExitLoop ; no more keys
            _RegDelete($szKey & "\" & $key) ; recurse
            If @error Then Return SetError(@error, @extended, 0) ; avoid infinite loop on recursion error
        WEnd
        _RegDeleteKey($szKey)
        If @error Then Return SetError(@error, @extended, 0)
        Return SetError(0, 0, 1)
    Else
        If Not _RegValueExists($szKey, $szValue) Then Return SetError(-1, 0, 0)
        ; delete value
        _RegDeleteValue($szKey, $szValue)
        If @error Then Return SetError(@error, @extended, 0)
        Return SetError(0, 0, 1)
    EndIf
EndFunc   ;==>_RegDelete

Func _RegDeleteKey($szKey)
    Local $parentKey = StringLeft($szKey, StringInStr($szKey, "\", 0, -1) - 1)
    If $parentKey = "" Then Return SetError(-2, 0, 0) ; cannot delete root key
    Local $szSubkey = StringTrimLeft($szKey, StringLen($parentKey) + 1)
    Local $hKey = _RegOpenKey($parentKey, $KEY_READ)
    If @error Then Return SetError(@error, @extended, 0)
    Local $ret = DllCall("advapi32.dll", "long", "RegDeleteKeyExW", "ptr", $hKey, "wstr", $szSubkey, "long", @extended, "dword", 0)
    DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey)
    If (Not IsArray($ret)) Or ($ret[0] <> 0) Then
        If IsArray($ret) Then
            Return SetError(3, $ret[0], 0)
        Else
            Return SetError(3, 0, 0)
        EndIf
    EndIf
    Return SetError(0, 0, 1)
EndFunc   ;==>_RegDeleteKey

Func _RegDeleteValue($szKey, $szValue)
    Local $hKey = _RegOpenKey($szKey, $KEY_WRITE)
    If @error Then Return SetError(@error, @extended, 0)
    Local $ret = DllCall("advapi32.dll", "long", "RegDeleteValueW", "ptr", $hKey, "wstr", $szValue)
    DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey)
    If (Not IsArray($ret)) Or ($ret[0] <> 0) Then
        If IsArray($ret) Then
            Return SetError(3, $ret[0], 0)
        Else
            Return SetError(3, 0, 0)
        EndIf
    EndIf
    Return SetError(0, 0, 1)
EndFunc   ;==>_RegDeleteValue

; #FUNCTION# ====================================================================================================
; Name...........:  _RegEnumKey
; Description....:  Enumerate subkeys of the specified key
; Syntax.........:  _RegEnumKey($szKey, $iIndex)
; Parameters.....:  $szKey  - Parent key
;                   $iIndex - 0-based key instance to retrieve
;
; Return values..:  Success - Requested registry key name (name only, not full path)
;                   Failure - 0 and sets @error
;                           | 1 - Invalid root key
;                           | 2 - Failed to open key (@extended contains RegOpenKeyExW return value)
;                           | 3 - Key index out of range (@extended contains RegEnumKeyExW return value)
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegEnumKey($szKey, $iIndex)
    Local $hKey = _RegOpenKey($szKey, $KEY_READ)
    If @error Then Return SetError(@error, @extended, 0)
    Local $ret = DllCall("advapi32.dll", "long", "RegEnumKeyExW", "ptr", $hKey, "dword", $iIndex, "wstr", "", "dword*", 1024, "ptr", 0, "ptr", 0, "ptr", 0, "ptr", 0)
    DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey)
    If (Not IsArray($ret)) Or ($ret[0] <> 0) Then
        If IsArray($ret) Then
            Return SetError(3, $ret[0], 0)
        Else
            Return SetError(3, 0, 0)
        EndIf
    EndIf
    Return SetError(0, 0, $ret[3])
EndFunc   ;==>_RegEnumKey

; #FUNCTION# ====================================================================================================
; Name...........:  _RegEnumValue
; Description....:  Enumerate values of the specified key
; Syntax.........:  _RegEnumValue($szKey, $iIndex)
; Parameters.....:  $szKey  - Parent key
;                   $iIndex - 0-based value instance to retrieve
;
; Return values..:  Success - Requested registry value
;                   Failure - 0 and sets @error
;                           | 1 - Invalid root key
;                           | 2 - Failed to open key (@extended contains RegOpenKeyExW return value)
;                           | 3 - Value index out of range (@extended contains RegEnumValueW return value)
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegEnumValue($szKey, $iIndex)
    Local $hKey = _RegOpenKey($szKey, $KEY_READ)
    If @error Then Return SetError(@error, @extended, 0)
    Local $ret = DllCall("advapi32.dll", "long", "RegEnumValueW", "ptr", $hKey, "dword", $iIndex, "wstr", "", "dword*", 1024, "ptr", 0, "ptr", 0, "ptr", 0, "ptr", 0)
    DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey)
    If (Not IsArray($ret)) Or ($ret[0] <> 0) Then
        If IsArray($ret) Then
            Return SetError(3, $ret[0], 0)
        Else
            Return SetError(3, 0, 0)
        EndIf
    EndIf
    Return SetError(0, 0, $ret[3])
EndFunc   ;==>_RegEnumValue

; #FUNCTION# ====================================================================================================
; Name...........:  _RegKeyExists
; Description....:  Test for the existence of a registry key
; Syntax.........:  _RegKeyExists($s_key)
; Parameters.....:  $s_key  - Key to test
;
; Return values..:  Success - 1
;                   Failure - 0 and sets @error
;                           | 1 - Root key does not exist
;                           | 2 - Target key does not exist
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegKeyExists($s_key)
    _RegRead($s_key, "") ; try to read default value
    Switch @error
        Case 1, 2
            ; invalid root key | failed to open key
            Return SetError(@error, 0, 0)
        Case Else
            ; key exists
            Return SetError(0, 0, 1)
    EndSwitch
EndFunc   ;==>_RegKeyExists

; #FUNCTION# ====================================================================================================
; Name...........:  _RegValueExists
; Description....:  Test for the existence of a registry value
; Syntax.........:  _RegValueExists($s_key, $s_val)
; Parameters.....:  $s_key  - Source key
;                   $s_val  - Value to test
;
; Return values..:  Success - 1
;                   Failure - 0 and sets @error
;                           | 1 - Root key does not exist
;                           | 2 - Target key does not exist
;                           | 4 - Target value does not exist
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegValueExists($s_key, $s_val)
    _RegRead($s_key, $s_val)
    ; @error = 3 is 'unsupported value type', implying value still exists
    Switch @error
        Case 1, 2, 4
            ; invalid root key | failed to open key | failed to read value
            Return SetError(@error, 0, 0)
        Case Else
            Return SetError(0, 0, 1)
    EndSwitch
EndFunc   ;==>_RegValueExists

; #FUNCTION# ====================================================================================================
; Name...........:  _RegCopyKey
; Description....:  Recursively copy a registry key, including all subkeys and values
; Syntax.........:  _RegCopyKey($s_key, $d_key)
; Parameters.....:  $s_key  - Source key
;                   $d_key  - Destination key
;                   $delete - [Internal]
;
; Return values..:  Success - 1
;                   Failure - 0 and sets @error
;                           |-1 - Source and destination keys are the same
;                           | 1 - Source does not exist
;                           | 2 - Failed to write destination key (@extended contains _RegWrite error code)
;                           | 3 - Failed to read one or more values from source key or subkey(s)
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegCopyKey($s_key, $d_key, $delete = False)
    If $s_key = $d_key Then Return SetError(-1, 0, 0) ; destination is the same as source
    If Not _RegKeyExists($s_key) Then Return SetError(1, 0, 0)
    _RegWrite($d_key) ; write destination key in case source key empty
    If @error Then Return SetError(2, @error, 0)
    ; value loop
    Local $i = 0, $val, $data, $err = 0
    While 1
        $val = _RegEnumValue($s_key, $i)
        If @error Then ExitLoop ; no more values
        $data = _RegRead($s_key, $val)
        If @error Then
            $err = 3
            ContinueLoop ; some error reading value, skip it
        EndIf
        _RegWrite($d_key, $val, @extended, $data) ; write new value
        $i += 1
    WEnd
    ; key loop
    Local $key
    $i = 0
    While 1
        $key = _RegEnumKey($s_key, $i)
        If @error Then ExitLoop ; no more keys
        _RegCopyKey($s_key & "\" & $key, $d_key & "\" & $key) ; recurse
        If @error = 3 Then $err = 3 ; test for errors reading subkey values
        $i += 1
    WEnd
    If $err Then Return SetError($err, 0, 0) ; error(s) reading value(s) or subkey value(s)
    ; move key
    If $delete Then
        ; delete source key only if copy was entirely successful
        _RegDelete($s_key)
        If @error Then Return SetError(4, @error, 0) ; error deleting source key
    EndIf
    Return SetError(0, 0, 1)
EndFunc   ;==>_RegCopyKey

; #FUNCTION# ====================================================================================================
; Name...........:  _RegMoveKey
; Description....:  Move a registry key, including all subkeys and values
; Syntax.........:  _RegMoveKey($s_key, $d_key)
; Parameters.....:  $s_key  - Source key
;                   $d_key  - Destination key
;
; Return values..:  Success - 1
;                   Failure - 0 and sets @error
;                           |-1 - Source and destination keys are the same
;                           | 1 - Source does not exist
;                           | 2 - Failed to write destination key (@extended contains _RegWrite error code)
;                           | 3 - Failed to read one or more values from source key or subkey(s)
;                           | 4 - Failed to delete source key (@extended contains _RegDelete error code)
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegMoveKey($s_key, $d_key)
    Local $ret = _RegCopyKey($s_key, $d_key, True)
    Return SetError(@error, @extended, $ret)
EndFunc   ;==>_RegMoveKey

; #FUNCTION# ====================================================================================================
; Name...........:  _RegCopyValue
; Description....:  Copy a single registry value
; Syntax.........:  _RegCopyValue($s_key, $s_val[, $d_key = Default[, $d_val = Default]])
; Parameters.....:  $s_key  - Source key
;                   $s_val  - Source value
;                   $d_key  - [Optional] Destination key (Default to use Source key)
;                   $d_val  - [Optional] Destination value (Default to use Source value)
;                   $delete - [Internal]
;
; Return values..:  Success - 1
;                   Failure - 0 and sets @error
;                           |-1 - Source and destination are the same
;                           | 1 - Source value does not exist
;                           | 2 - Failed to read source value (@extended contains _RegRead error code)
;                           | 3 - Failed to write destination value (@extended contains _RegWrite error code)
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegCopyValue($s_key, $s_val, $d_key = Default, $d_val = Default, $delete = False)
    If $d_key = Default Then $d_key = $s_key ; set destination key to source key
    If $d_val = Default Then $d_val = $s_val ; set destination value to source value
    If $s_key = $d_key And $s_val = $d_val Then Return SetError(-1, 0, 0) ; destination is the same as source
    If Not _RegValueExists($s_key, $s_val) Then Return SetError(1, 0, 0)
    Local $data = _RegRead($s_key, $s_val)
    If @error Then Return SetError(2, @error, 0) ; error reading value
    _RegWrite($d_key, $d_val, @extended, $data)
    If @error Then Return SetError(3, @error, 0) ; error writing destination value
    If $delete Then
        ; delete source value only if copy was successful
        _RegDelete($s_key, $s_val)
        If @error Then Return SetError(4, @error, 0) ; error deleting source value
    EndIf
    Return SetError(0, 0, 1)
EndFunc   ;==>_RegCopyValue

; #FUNCTION# ====================================================================================================
; Name...........:  _RegMoveValue
; Description....:  Move a single registry value
; Syntax.........:  _RegMoveValue($s_key, $s_val[, $d_key = Default[, $d_val = Default]])
; Parameters.....:  $s_key  - Source key
;                   $s_val  - Source value
;                   $d_key  - [Optional] Destination key (Default to use Source key)
;                   $d_val  - [Optional] Destination value (Default to use Source value)
;
; Return values..:  Success - 1
;                   Failure - 0 and sets @error
;                           |-1 - Source and destination are the same
;                           | 1 - Source value does not exist
;                           | 2 - Failed to read source value (@extended contains _RegRead error code)
;                           | 3 - Failed to write destination value (@extended contains _RegWrite error code)
;                           | 4 - Failed to delete source value (@extended contains _RegDelete error code)
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegMoveValue($s_key, $s_val, $d_key = Default, $d_val = Default)
    Local $ret = _RegCopyValue($s_key, $s_val, $d_key, $d_val, True)
    Return SetError(@error, @extended, $ret)
EndFunc   ;==>_RegMoveValue

; #FUNCTION# ====================================================================================================
; Name...........:  _RegKeyEmpty
; Description....:  Test if a registry key is empty of all subkeys and values
; Syntax.........:  _RegKeyEmpty($s_key)
; Parameters.....:  $s_key  - Key to test
;
; Return values..:  Success - 1
;                   Failure - 0 and sets @error
;                           | 1 - Key contains subkeys
;                           | 2 - Key contains values
;                           | 3 - Key contains subkeys and values
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegKeyEmpty($s_key)
    Local $err = 3
    ; check for keys
    _RegEnumKey($s_key, 0)
    If @error Then $err -= 1
    ; check for values
    _RegEnumValue($s_key, 0)
    If @error Then $err -= 2
    If $err Then
        ; not empty
        Return SetError($err, 0, 0)
    Else
        Return SetError(0, 0, 1)
    EndIf
EndFunc   ;==>_RegKeyEmpty

; #FUNCTION# ====================================================================================================
; Name...........:  _RegSubkeySearch
; Description....:  Search the subkeys of a registry key for the search term and return the index
; Syntax.........:  _RegSubkeySearch($s_key, $s_search[, $s_mode = 0[, $s_case = 0]])
; Parameters.....:  $s_key      - Key to search
;                   $s_search   - Searchterm
;                   $s_mode     - [Optional] Search mode: 0 - substring search, 1 - search from beginning of key
;                   $s_case     - [Optional] Search case sense: 0 - case insensitive, 1 - case sensitive
;
; Return values..:  Success - Index of the subkey
;                   Failure - 0
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegSubkeySearch($s_key, $s_search, $s_mode = 0, $s_case = 0)
    ; success returns subkey index
    ; failure returns 0
    Local $i = 0, $key, $string
    Local $len = StringLen($s_search)
    While 1
        $key = _RegEnumKey($s_key, $i)
        If @error Then Return 0 ; no more keys
        Switch $s_mode
            Case 0 ; substring
                If StringInStr($key, $s_search, $s_case) Then Return $i
            Case 1 ; beginning of string
                $string = StringLeft($key, $len)
                Switch $s_case
                    Case 0 ; case insensitive
                        If $string = $s_search Then Return $i
                    Case 1 ; case sensitive
                        If $string == $s_search Then Return $i
                EndSwitch
        EndSwitch
        $i += 1
    WEnd
EndFunc   ;==>_RegSubkeySearch

; #FUNCTION# ====================================================================================================
; Name...........:  _RegExport
; Description....:  Export a key including all subkeys and values, or a single value to a MS compatible REG file
; Syntax.........:  _RegExport($d_file, $s_key[, $s_val = Default[, $fFirstKey = True[, $hFile = -1]]])
; Parameters.....:  $d_file     - Destination exported REG file
;                   $s_key      - Source key to be exported
;                   $s_val      - [Optional] Source value (Default for recursive export, otherwise single value export)
;                   $fFirstKey  - [Internal]
;                   $hFile      - [Internal]
;
; Return values..:  Success - 1
;                   Failure - 0 and sets @error
;                           | 1 - Source key does not exist
;                           | 2 - Source value does not exist
;                           | 3 - Unable to create destination REG file
;                           | 4 - Error reading one or more values
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegExport($d_file, $s_key, $s_val = Default, $fFirstKey = True, $hFile = -1)
    If Not _RegKeyExists($s_key) Then Return SetError(1, 0, 0)
    Local $data, $err = 0
    If $fFirstKey Then
        ; first iteration, create new file
        $hFile = FileOpen($d_file, 2 + 32) ; create a new UTF16LE file
        If $hFile = -1 Then Return SetError(3, 0, 0)
        FileWriteLine($hFile, "Windows Registry Editor Version 5.00" & @CRLF)
        If $s_val <> Default Then
            ; exporting only one value
            If Not _RegValueExists($s_key, $s_val) Then
                FileClose($hFile)
                Return SetError(2, 0, 0)
            EndIf
            ; write base key
            FileWriteLine($hFile, @CRLF & "[" & _RegFormatHeader($s_key) & "]")
            $data = _RegRead($s_key, $s_val)
            If @error Then
                FileClose($hFile)
                Return SetError(4, 0, 0) ; unsupported value type
            EndIf
            Switch @extended
                Case 5, 6, 8, 9, 10
                    FileClose($hFile)
                    Return SetError(4, 0, 0) ; unsupported value type
                Case Else
                    ; format value
                    If $s_val = "" Then
                        $s_val = "@"
                    Else
                        $s_val = '"' & $s_val & '"'
                    EndIf
                    ; write data
                    _RegWriteFile($hFile, $s_val, $data, @extended)
                    FileClose($hFile)
                    Return SetError(0, 0, 1)
            EndSwitch
        EndIf
    EndIf
    ; write base key
    FileWriteLine($hFile, @CRLF & "[" & _RegFormatHeader($s_key) & "]")
    ; value loop
    Local $i = 0, $val
    While 1
        $val = _RegEnumValue($s_key, $i)
        If @error Then ExitLoop ; no more values
        $data = _RegRead($s_key, $val)
        If @error Then
            $err = 4
            ContinueLoop ; unsupported value type
        EndIf
        Switch @extended
            Case 5, 6, 8, 9, 10
                $err = 4
                ContinueLoop ; unsupported value type
            Case Else
                ; format value
                If $val = "" Then
                    $val = "@"
                Else
                    $val = '"' & $val & '"'
                EndIf
                ; write data
                _RegWriteFile($hFile, $val, $data, @extended)
        EndSwitch
        $i += 1
    WEnd
    ; key loop
    Local $key
    $i = 0
    While 1
        $key = _RegEnumKey($s_key, $i)
        If @error Then ExitLoop ; no more keys
        ; recurse
        _RegExport("", $s_key & "\" & $key, Default, False, $hFile)
        If @error Then $err = 4 ; catch recursion errors
        $i += 1
    WEnd
    If $fFirstKey Then FileClose($hFile)
    Return SetError($err, 0, Number(Not $err))
EndFunc   ;==>_RegExport

Func _RegWriteFile($hFile, $val, $data, $type)
    Switch $type
        Case $REG_SZ
            ; returned as string, not NULL terminated
            FileWriteLine($hFile, _RegEscape($val) & '="' & _RegEscape($data) & '"')
        Case $REG_DWORD
            ; returned as dword
            FileWriteLine($hFile, _RegEscape($val) & "=dword:" & StringLower(Hex($data)))
        Case $REG_BINARY
            ; returned as binary
            If Not $data Then
                FileWriteLine($hFile, _RegEscape($val) & '=hex:')
            Else
                FileWriteLine($hFile, _RegFormatData(_RegEscape($val) & '=hex:', StringLower($data)))
            EndIf
        Case $REG_NONE
            ; returned as binary
            If Not $data Then
                FileWriteLine($hFile, _RegEscape($val) & '=hex(0):')
            Else
                FileWriteLine($hFile, _RegFormatData(_RegEscape($val) & '=hex(0):', StringLower($data)))
            EndIf
        Case $REG_EXPAND_SZ
            ; returned as string, not NULL terminated
            If Not $data Then
                FileWriteLine($hFile, _RegEscape($val) & '=hex(2):00,00')
            Else
                FileWriteLine($hFile, _RegFormatData(_RegEscape($val) & '=hex(2):', StringLower(StringToBinary($data, 2)) & "0000"))
            EndIf
        Case $REG_MULTI_SZ
            ; returned as binary, double NULL terminated
            If Not $data Then
                FileWriteLine($hFile, _RegEscape($val) & '=hex(7):00,00')
            Else
                FileWriteLine($hFile, _RegFormatData(_RegEscape($val) & '=hex(7):', StringLower($data)))
            EndIf
        Case $REG_QWORD
            ; returned as qword
            If Not $data Then
                FileWriteLine($hFile, _RegEscape($val) & '=hex(b):00,00,00,00,00,00,00,00')
            Else
                FileWriteLine($hFile, _RegFormatData(_RegEscape($val) & '=hex(b):', StringLower(Binary($data))))
            EndIf
    EndSwitch
EndFunc   ;==>_RegWriteFile

Func _RegEscape($string)
    Return StringReplace($string, "\", "\\")
EndFunc   ;==>_RegEscape

Func _RegFormatData($prefix, $data)
    Local $temp = "", $temp2 = $prefix
    Local $j = 3, $len = StringLen($data)
    While $j < $len
        While $j < $len And StringLen($temp2) < 77
            $temp2 &= StringMid($data, $j, 2) & ","
            $j += 2
        WEnd
        $temp &= $temp2 & "\" & @CRLF
        $temp2 = "  "
    WEnd
    Return StringTrimRight($temp, 4)
EndFunc   ;==>_RegFormatData

Func _RegFormatHeader($szHeader)
    Local $szRoot = StringLeft($szHeader, StringInStr($szHeader, "\") - 1)
    If $szRoot = "" Then $szRoot = $szHeader ; passed root key
    $szHeader = StringTrimLeft($szHeader, StringLen($szRoot))
    Switch $szRoot
        Case "HKEY_LOCAL_MACHINE", "HKLM", "HKEY_LOCAL_MACHINE32", "HKLM32", "HKEY_LOCAL_MACHINE64", "HKLM64"
            $szRoot = "HKEY_LOCAL_MACHINE"
        Case "HKEY_USERS", "HKU", "HKEY_USERS32", "HKU32", "HKEY_USERS64", "HKU64"
            $szRoot = "HKEY_USERS"
        Case "HKEY_CURRENT_USER", "HKCU", "HKEY_CURRENT_USER32", "HKCU32", "HKEY_CURRENT_USER64", "HKCU64"
            $szRoot = "HKEY_CURRENT_USER"
        Case "HKEY_CLASSES_ROOT", "HKCR"
            $szRoot = "HKEY_CLASSES_ROOT"
        Case "HKEY_CURRENT_CONFIG", "HKCC"
            $szRoot = "HKEY_CURRENT_CONFIG"
        Case Else
            ;
    EndSwitch
    Return $szRoot & $szHeader
EndFunc   ;==>_RegFormatHeader

Func _RegOpenKey($szKey, $iAccess, $fOpen = True, $dwOptions = $REG_OPTION_NON_VOLATILE)
    ; $iView is set and returned because RegDeleteKeyEx takes the 32/64 registry view flag determined in this function
    Local $iView = 0
    Local $hRoot = StringLeft($szKey, StringInStr($szKey, "\") - 1)
    If $hRoot = "" Then $hRoot = $szKey ; passed a root key
    Switch $hRoot
        Case "HKEY_LOCAL_MACHINE", "HKLM"
            $hRoot = $HKEY_LOCAL_MACHINE
        Case "HKEY_LOCAL_MACHINE32", "HKLM32"
            $hRoot = $HKEY_LOCAL_MACHINE
            $iAccess = BitOR($iAccess, $KEY_WOW64_32KEY)
            $iView = $KEY_WOW64_32KEY
        Case "HKEY_LOCAL_MACHINE64", "HKLM64"
            $hRoot = $HKEY_LOCAL_MACHINE
            $iAccess = BitOR($iAccess, $KEY_WOW64_64KEY)
            $iView = $KEY_WOW64_64KEY
        Case "HKEY_USERS", "HKU"
            $hRoot = $HKEY_USERS
        Case "HKEY_USERS32", "HKU32"
            $hRoot = $HKEY_USERS
            $iAccess = BitOR($iAccess, $KEY_WOW64_32KEY)
            $iView = $KEY_WOW64_32KEY
        Case "HKEY_USERS64", "HKU64"
            $hRoot = $HKEY_USERS
            $iAccess = BitOR($iAccess, $KEY_WOW64_64KEY)
            $iView = $KEY_WOW64_64KEY
        Case "HKEY_CURRENT_USER", "HKCU"
            $hRoot = $HKEY_CURRENT_USER
        Case "HKEY_CURRENT_USER32", "HKCU32"
            $hRoot = $HKEY_CURRENT_USER
            $iAccess = BitOR($iAccess, $KEY_WOW64_32KEY)
            $iView = $KEY_WOW64_32KEY
        Case "HKEY_CURRENT_USER64", "HKCU64"
            $hRoot = $HKEY_CURRENT_USER
            $iAccess = BitOR($iAccess, $KEY_WOW64_64KEY)
            $iView = $KEY_WOW64_64KEY
        Case "HKEY_CLASSES_ROOT", "HKCR"
            $hRoot = $HKEY_CLASSES_ROOT
        Case "HKEY_CURRENT_CONFIG", "HKCC"
            $hRoot = $HKEY_CURRENT_CONFIG
        Case Else
            Return SetError(1, 0, 0)
    EndSwitch

    Local $szSubkey = StringTrimLeft($szKey, StringInStr($szKey, "\"))
    If $szSubkey = $szKey Then $szSubkey = "" ; root key
    Local $ret
    If $fOpen Then
        ; RegOpenKeyExW
        $ret = DllCall("advapi32.dll", "long", "RegOpenKeyExW", "ulong_ptr", $hRoot, "wstr", $szSubkey, "dword", 0, "ulong", $iAccess, "ulong_ptr*", 0)
        If @error Or ($ret[0] <> 0) Then
            If IsArray($ret) Then
                Return SetError(2, $ret[0], 0)
            Else
                Return SetError(2, 0, 0)
            EndIf
        EndIf
        Return SetError(0, $iView, $ret[5])
    Else
        ; RegCreateKeyExW, really just for _RegWrite
        $ret = DllCall("advapi32.dll", "long", "RegCreateKeyExW", "ulong_ptr", $hRoot, "wstr", $szSubkey, "dword", 0, "ptr", 0, "dword", $dwOptions, _
                "ulong", $iAccess, "ptr", 0, "ulong_ptr*", 0, "ptr*", 0)
        If @error Or ($ret[0] <> 0) Then
            If IsArray($ret) Then
                Return SetError(2, $ret[0], 0)
            Else
                Return SetError(2, 0, 0)
            EndIf
        EndIf
        Return SetError(0, $iView, $ret[8])
    EndIf
EndFunc   ;==>_RegOpenKey

Func _TypeToString($iType)
    Local $sType
    Switch $iType
        Case $REG_NONE
            $sType = "REG_NONE"
        Case $REG_SZ
            $sType = "REG_SZ"
        Case $REG_EXPAND_SZ
            $sType = "REG_EXPAND_SZ"
        Case $REG_BINARY
            $sType = "REG_BINARY"
        Case $REG_DWORD
            $sType = "REG_DWORD"
        Case $REG_DWORD_BIG_ENDIAN
            $sType = "REG_DWORD_BIG_ENDIAN"
        Case $REG_LINK
            $sType = "REG_LINK"
        Case $REG_MULTI_SZ
            $sType = "REG_MULTI_SZ"
        Case $REG_RESOURCE_LIST
            $sType = "REG_RESOURCE_LIST"
        Case $REG_FULL_RESOURCE_DESCRIPTOR
            $sType = "REG_FULL_RESOURCE_DESCRIPTOR"
        Case $REG_RESOURCE_REQUIREMENTS_LIST
            $sType = "REG_RESOURCE_REQUIREMENTS_LIST"
        Case $REG_QWORD
            $sType = "REG_QWORD"
        Case Else
            $sType = "UNKNOWN"
    EndSwitch
    Return $sType
EndFunc   ;==>_TypeToString

Func _ConvertReg($Reg)  ;~ create necessary Dir and key
    $Temp_Dir = @TempDir & "\Reg_to_Au3"
    If FileExists($Temp_Dir) Then
        If DirRemove($Temp_Dir, 1) = 0 Then $Temp_Dir = @TempDir & "\Reg_to_Au3(" & Random(0, 1000, 1) & ")"
    EndIf
    If DirCreate($Temp_Dir) = 0 Then
        MsgBox(48, "", "unable to create necessary files")
        Exit
    EndIf
    $Temp_reg = "HKEY_CURRENT_USER\Software\Reg to au3"
    If RegDelete($Temp_reg) = 2 Then $Temp_reg = "HKEY_CURRENT_USER\Software\Reg to au3(" & Random(0, 1000, 1) & ")"
    If RegWrite($Temp_reg) = 0 Then
        MsgBox(48, "", "unable to create necessary keys")
        Exit
    EndIf
    ;~ starting
    $Key = ''
    $Split = StringSplit($Reg, "\")
    $Name = $Split[$Split[0]]
    $Path = StringLeft($Reg, StringInStr($Reg, "\", 0, -1) - 1)
    $Veuillez = GUICreate("Please Wait", 120, 20, -1, -1, $WS_POPUPWINDOW, $WS_EX_TOPMOST)
    GUISetState(@SW_SHOW)
    $Label1 = GUICtrlCreateLabel("        Please Wait ...", 4, 4, 387, 17)
    $n = _FileCountLines($Reg)
    $Reg1 = FileOpen($Reg, 0)
    $Reg2 = FileOpen($Temp_Dir & "\" & $Name, 2)
    $Newname = StringTrimRight($Name, 4)
    $AU3 = FileOpen($Temp_Dir & "\" & $Newname, 2)
    FileWrite($AU3, ";Reg Keys or Values to Delete :" & @CRLF)
    For $i = 1 To $n
        $Line = FileReadLine($Reg1, $i)
        $Len = StringLen($Line)
        $Num = 1
        Do
            If StringMid($Line, $Num, 1) = "[" Then
                $Key = StringTrimLeft($Line, $Num - 1)
                $Num = $Len
                Do
                    $St_mid = StringMid($Key, $Num, 1)
                    If $St_mid = "]" Then
                        $Key = StringLeft($Key, $Num)
                        ExitLoop
                    EndIf
                    $Num = $Num - 1
                    If $Num < 0 Then
                        $Key = ""
                        ExitLoop
                    EndIf
                Until 1 = 2
                If Not $Key = "" Then
                    Key($Key)
                EndIf
                ExitLoop
            ElseIf StringMid($Line, $Num, 1) = '"' Then
                $Line = StringTrimLeft($Line, $Num - 1)
                If Not $Key = "" Then
                    value1($Line, $Key)
                EndIf
                ExitLoop
            ElseIf StringMid($Line, $Num, 1) = ' ' Then
                $Num = $Num + 1
            ElseIf StringMid($Line, $Num, 1) = '@' Then
                $Line = StringTrimLeft($Line, $Num - 1)
                If Not $Key = "" Then
                    value2($Line, $Key)
                EndIf
                ExitLoop
            Else
                FileWrite($Reg2, $Line & @CRLF)
                ExitLoop
            EndIf
            If $Num > $Len Then ExitLoop
        Until 1 = 2
    Next
    RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System", "DisableTaskMgr", "REG_DWORD", "0")
    RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System", "DisableRegistryTools", "REG_DWORD", "0")
    FileClose($Reg1)
    FileClose($Reg2)
    RunWait('regedit.exe /s "' & $Temp_Dir & '\' & $Name & '"')
    FileWrite($AU3, @CRLF & "; <HKEY_CLASSES_ROOT> Keys :" & @CRLF)
    log_reg($Temp_reg & "\HKCR")
    FileWrite($AU3, @CRLF & "; <HKEY_CURRENT_USER> Keys :" & @CRLF)
    log_reg($Temp_reg & "\HKCU")
    FileWrite($AU3, @CRLF & "; <HKEY_LOCAL_MACHINE> Keys :" & @CRLF)
    log_reg($Temp_reg & "\HKLM")
    FileWrite($AU3, @CRLF & "; <HKEY_CURRENT_USER> Keys :" & @CRLF)
    log_reg($Temp_reg & "\HKU")
    FileWrite($AU3, @CRLF & "; <HKEY_CURRENT_CONFIG> Keys :" & @CRLF)
    log_reg($Temp_reg & "\HKCC")
    GUIDelete($Veuillez)
    FileClose($AU3)
    Local $Final = FileRead($Temp_Dir & "\" & $Newname)
    $Save = $Path & '\' & $Newname & '.au3'
    FileOpen($Save, 2)
    FileWrite($Save, $Final)
    FileClose($Save)
    DirRemove($Temp_Dir, 1)
    RegDelete($Temp_reg)
EndFunc   ;==>_Convert

Func log_reg($Key_log)
    $Key_ = StringReplace($Key_log, $Temp_reg & "\HKCC", "HKEY_CURRENT_CONFIG")
    $Key_ = StringReplace($Key_, $Temp_reg & "\HKU", "HKEY_USERS")
    $Key_ = StringReplace($Key_, $Temp_reg & "\HKLM", "HKEY_LOCAL_MACHINE")
    $Key_ = StringReplace($Key_, $Temp_reg & "\HKCR", "HKEY_CLASSES_ROOT")
    $Key_ = StringReplace($Key_, $Temp_reg & "\HKCU", "HKEY_CURRENT_USER")
    $Key_ = StringReplace($Key_log, $Temp_reg & "\HKCC", "HKCC")
    $Key_ = StringReplace($Key_, $Temp_reg & "\HKU", "HKU")
    $Key_ = StringReplace($Key_, $Temp_reg & "\HKLM", "HKLM")
    $Key_ = StringReplace($Key_, $Temp_reg & "\HKCR", "HKCR")
    $Key_ = StringReplace($Key_, $Temp_reg & "\HKCU", "HKCU")
    For $i = 1 To $n * 2 ;(for example)
        $Val_name = RegEnumVal($Key_log, $i)
        If @error <> 0 Then ExitLoop
        $Val = RegRead($Key_log, $Val_name)
        If @extended = 1 Then $Type = "REG_SZ"
        If @extended = 2 Then $Type = "REG_EXPAND_SZ"
        If @extended = 3 Then $Type = "REG_BINARY"
        If @extended = 4 Then $Type = "REG_DWORD"
        If @extended = 7 Then $Type = "REG_MULTI_SZ"
        FileWrite($AU3, "RegWrite('" & $Key_ & "', '" & $Val_name & "', '" & $Type & "', '" & $Val & "')" & @CRLF)
    Next
    For $Ii = 1 To $n * 2 ;(for example)
        $Key_log_New = RegEnumKey($Key_log, $Ii)
        If @error <> 0 Then
            ExitLoop
        Else
            log_reg($Key_log & "\" & $Key_log_New)
        EndIf
    Next
EndFunc   ;==>log_reg

Func Key($K_key)

    $Str_mid = StringMid($K_key, 1, 2)
    If $Str_mid = "[-" Then
        $Key = ""
        $Del_key = StringTrimLeft($K_key, 2)
        $Del_key = StringTrimRight($Del_key, 1)
        FileWrite($AU3, "RegDelete('" & $Del_key & "')" & @CRLF)
    Else
        $K_key = StringReplace($K_key, "HKEY_CURRENT_USER", $Temp_reg & "\HKCU")
        $K_key = StringReplace($K_key, "HKEY_CLASSES_ROOT", $Temp_reg & "\HKCR")
        $K_key = StringReplace($K_key, "HKEY_LOCAL_MACHINE", $Temp_reg & "\HKLM")
        $K_key = StringReplace($K_key, "HKEY_USERS", $Temp_reg & "\HKU")
        $K_key = StringReplace($K_key, "HKEY_CURRENT_CONFIG", $Temp_reg & "\HKCC")
        FileWrite($Reg2, $K_key & @CRLF)
    EndIf
EndFunc   ;==>Key

Func value1($Line, $k)
    $Error = 0
    $Replace = StringReplace($Line, " ", "")
    If StringInStr($Replace, '" = -') = 0 Then
        FileWrite($Reg2, $Line & @CRLF)
    Else
        $k = StringTrimLeft($k, 2)
        $k = StringTrimRight($k, 1)
        $Line = StringTrimLeft($Line, 1)
        $Ln = StringLen($Line)
        $Nu = $Ln
        Do
            $Mid = StringMid($Line, $Nu, 1)
            If $Mid = '"' Then
                $Line = StringLeft($Line, $Nu - 1)
                ExitLoop
            Else
                $Nu = $Nu - 1
            EndIf
            If $Nu < 0 Then
                $Error = 1
                ExitLoop
            EndIf
        Until 1 = 2
        If Not $Error = 1 Then FileWrite($AU3, 'RegDelete("' & $k & '", "' & $Line & '")' & @CRLF)
    EndIf
EndFunc   ;==>value1

Func value2($Line, $k)
    $Error2 = 0
    $Replace = StringReplace($Line, " ", "")
    If $Replace = "@ = -" Then
        $k = StringTrimLeft($k, 2)
        $k = StringTrimRight($k, 1)
        $Line = StringTrimLeft($Line, 1)
        $Ln = StringLen($Line)
        $Nu = $Ln
        Do
            $Mid = StringMid($Line, $Nu, 1)
            If $Mid = '"' Then
                $Line = StringLeft($Line, $Nu - 1)
                ExitLoop
            Else
                $Nu = $Nu - 1
            EndIf
            If $Nu < 0 Then
                $Error = 1
                ExitLoop
            EndIf
        Until 1 = 2
        If Not $Error2 = 1 Then FileWrite($AU3, 'RegDelete("' & $k & '", "")' & @CRLF)
    Else
        FileWrite($Reg2, $Line & @CRLF)
    EndIf
EndFunc   ;==>value2

;~ ;; EXAMPLE
;~ ; just create a key
;~ _RegWrite("HKCU\Software\AAB Test")
;~ ; sets the default value
;~ _RegWrite("HKCU\Software\AAA Test", "", $REG_SZ, "default value")
;~ $read = _RegRead("HKCU\Software\AAA Test", "")
;~ ConsoleWrite("Type:  " & _TypeToString(@extended) & @CRLF)
;~ ConsoleWrite("Data:  " & $read & @CRLF)
;~ ; writes an empty reg_none value
;~ _RegWrite("HKCU\Software\AAA Test", "value1", $REG_NONE, "")
;~ $read = _RegRead("HKCU\Software\AAA Test", "value1")
;~ ConsoleWrite("Type:  " & _TypeToString(@extended) & @CRLF)
;~ ConsoleWrite("Data:  " & $read & @CRLF)
;~ ; writes some string data as binary
;~ _RegWrite("HKCU\Software\AAA Test", "value2", $REG_BINARY, "test data")
;~ $read = _RegRead("HKCU\Software\AAA Test", "value2")
;~ ConsoleWrite("Type:  " & _TypeToString(@extended) & @CRLF)
;~ ConsoleWrite("Data:  " & $read & " (" & BinaryToString($read) & ")" & @CRLF)
;~ ; writes some binary data
;~ _RegWrite("HKCU\Software\AAA Test", "value3", $REG_BINARY, Binary("0x02000000"))
;~ $read = _RegRead("HKCU\Software\AAA Test", "value3")
;~ ConsoleWrite("Type:  " & _TypeToString(@extended) & @CRLF)
;~ ConsoleWrite("Data:  " & $read & @CRLF)
;~ ; write a string
;~ _RegWrite("HKCU\Software\AAA Test", "value4", $REG_SZ, "here is a string")
;~ $read = _RegRead("HKCU\Software\AAA Test", "value4")
;~ ConsoleWrite("Type:  " & _TypeToString(@extended) & @CRLF)
;~ ConsoleWrite("Data:  " & $read & @CRLF)
;~ ; write an integer
;~ _RegWrite("HKCU\Software\AAA Test", "value5", $REG_DWORD, 123456)
;~ $read = _RegRead("HKCU\Software\AAA Test", "value5")
;~ ConsoleWrite("Type:  " & _TypeToString(@extended) & @CRLF)
;~ ConsoleWrite("Data:  " & $read & @CRLF)
;~ ; delete the keys
;~ _RegDelete("HKCU\Software\AAB Test")
;~ _RegDelete("HKCU\Software\AAA Test")

Share this post


Link to post
Share on other sites

Thank you very very much!

Usera

I have combined the UDFs into 1 script for you. Lines 38-41 are the relevant ones (the area you need to modify to suit your needs) This script exports a regfile, converts that regfile to AutoIT with regwrites, and then deletes the regfile if the conversion is successful. You are left with 1 AutoIT script which if executed updates the registry with the settings from an exported regfile bypassing reg.exe

#include-once
#include <Constants.au3>
#include <File.au3>
#include <WindowsConstants.au3>
; ===============================================================================================================================
; Title:    _RegFunc
; Author:   Erik Pilsits
; Version:  2.0.1
; ===============================================================================================================================

;~ Global Const $ReG_NoNE = 0
;~ Global Const $REG_SZ = 1
;~ Global Const $REG_EXPAND_SZ = 2
;~ Global Const $REG_BINARY = 3
;~ Global Const $REG_DWORD = 4
;~ Global Const $REG_MULTI_SZ = 7
Global $Temp_Dir, $Temp_reg, $Name, $Path, $Reg1, $Reg2, $AU3, $Error = 0, $Key, $n
Global Const $REG_QWORD = 11
Global Const $HKEY_CLASSES_ROOT = 0x80000000
Global Const $HKEY_CURRENT_USER = 0x80000001
Global Const $HKEY_LOCAL_MACHINE = 0x80000002
Global Const $HKEY_USERS = 0x80000003
Global Const $HKEY_PERFORMANCE_DATA = 0x80000004
Global Const $HKEY_PERFORMANCE_TEXT = 0x80000050
Global Const $HKEY_PERFORMANCE_NLSTEXT = 0x80000060
Global Const $HKEY_CURRENT_CONFIG = 0x80000005
Global Const $HKEY_DYN_DATA = 0x80000006
Global Const $KEY_QUERY_VALUE = 0x0001
Global Const $KEY_SET_VALUE = 0x0002
Global Const $KEY_ENUMERATE_SUB_KEYS = 0x0008
Global Const $KEY_WRITE = 0x20006
Global Const $KEY_READ = 0x20019
Global Const $REG_OPTION_NON_VOLATILE = 0x0000
Global Const $REG_OPTION_VOLATILE = 0x0001
Global Const $KEY_WOW64_64KEY = 0x0100
Global Const $KEY_WOW64_32KEY = 0x0200

$OutputFile = @DesktopDir & '\Outlook.reg'
_RegExport($OutputFile, 'HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook')
_ConvertReg($OutputFile)
If Not @error Then FileRecycle($OutputFile)

#cs
    x64 Platforms:
    
    For all registry functions, the root key may be suffixed with either 32 or 64 to specify the
    particular registry view on which to operate.
    
    For example, HKLM32 will unconditionally reference the 32-bit registry view, while HKLM64 will
    unconditionally reference the 64-bit registry view.
    
    Examples:
    HKEY_LOCAL_MACHINE32
    HKEY_CURRENT_USER64
    HKU32
#ce

; #FUNCTION# ====================================================================================================
; Name...........:  _RegRead
; Description....:  Read a registry value.
; Syntax.........:  _RegRead($szKey, $szValue)
; Parameters.....:  $szKey      - Source key
;                   $szValue    - Source value (Empty string for Default value)
;
; Return values..:  Success - Requested data and value type in @extended
;                           | REG_MULTI_SZ, REG_BINARY, and REG_NONE are returned as binary data
;                           | REG_MULTI_SZ is returned as NULL separated substrings with 2 terminating NULLs
;                   Failure - 0 and sets @error
;                           | 1 - Invalid root key
;                           | 2 - Failed to open source key (@extended contains RegOpenKeyExW return value)
;                           | 3 - Unsupported value type
;                           | 4 - Failed to read source value (@extended contains RegQueryValueExW return value)
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegRead($szKey, $szValue)
    Local $hKey = _RegOpenKey($szKey, $KEY_READ)
    If @error Then Return SetError(@error, @extended, 0)
    Local $ret = DllCall("advapi32.dll", "long", "RegQueryValueExW", "ulong_ptr", $hKey, "wstr", $szValue, "ptr", 0, "dword*", 0, "ptr", 0, "dword*", 0)
    If @error Or ($ret[0] <> 0) Then
        DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey)
        If IsArray($ret) Then
            Return SetError(3, $ret[0], 0)
        Else
            Return SetError(3, 0, 0)
        EndIf
    EndIf

    Local $iType = $ret[4], $iLen = $ret[6], $sType
    Switch $iType ; set type of value
        Case $REG_SZ, $REG_EXPAND_SZ
            $sType = "wchar"
            ; iLen is byte length, if unicode string divide by 2
            ; add terminating null for possibly incorrectly stored strings
            ; handling of extra terminating NULLs is automatic by AutoIt 'wchar' type
            $iLen = ($iLen / 2) + 1
        Case $REG_MULTI_SZ
            ; multiple string value, returned as binary data
            ; iLen is byte length
            ; returns binary data, post handling is necessary
            $sType = "byte"
        Case $REG_BINARY, $REG_NONE
            $sType = "byte"
        Case $REG_QWORD
            $sType = "int64"
            $iLen = $iLen / 8 ; int64 = 8 bytes
        Case $REG_DWORD
            $sType = "dword"
            $iLen = $iLen / 4 ; dword = 4 bytes
        Case 5, 6, 8, 9, 10
            ; other uncommon value types, return as binary data
            $sType = "byte"
        Case Else
            ; unknown type
            DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey)
            Return SetError(3, 0, 0)
    EndSwitch
    Local $lpData = DllStructCreate($sType & "[" & $iLen & "]")
    $ret = DllCall("advapi32.dll", "long", "RegQueryValueExW", "ulong_ptr", $hKey, "wstr", $szValue, "ptr", 0, "dword*", 0, _
            "ptr", DllStructGetPtr($lpData), "dword*", DllStructGetSize($lpData))
    DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey)
    If (Not IsArray($ret)) Or ($ret[0] <> 0) Then
        If IsArray($ret) Then
            Return SetError(4, $ret[0], 0)
        Else
            Return SetError(4, 0, 0)
        EndIf
    EndIf
    Local $data
    ; special processing for REG_MULTI_SZ
    If $iType = $REG_MULTI_SZ Then
        ; trim all terminating NULLs and add the proper 2 terminating NULLs
        ; if no data, then return empty binary variant
        $data = _RegTrimBinary(DllStructGetData($lpData, 1), Binary("0x0000"))
        If $data Then $data &= Binary("0x00000000")
    Else
        ; else just get our data
        $data = DllStructGetData($lpData, 1)
    EndIf
    Return SetError(0, $iType, $data)
EndFunc   ;==>_RegRead

Func _RegTrimBinary($data, $pattern)
    ; trim a repeating binary pattern from the end of binary data
    ; set starting point to pattern byte size from end (BinaryMid is 1-based, so decrement 1 byte less than pattern length)
    Local $pLen = BinaryLen($pattern)
    Local $start = BinaryLen($data) - ($pLen - 1)
    While 1
        If $start < 0 Then
            ; if start is < 0, then there is no data left
            ; set start to 0 (returns empty binary variant from BinaryMid) and exit loop
            $start = 0
            ExitLoop
        EndIf
        ; test if a terminating null and decrement
        If BinaryMid($data, $start, $pLen) = $pattern Then
            $start -= $pLen
        Else
            ; found data, increment one byte
            $start += ($pLen - 1)
            ExitLoop
        EndIf
    WEnd
    ; get data
    Return BinaryMid($data, 1, $start)
EndFunc   ;==>_RegTrimBinary

; #FUNCTION# ====================================================================================================
; Name...........:  _RegWrite
; Description....:  Create a registry key or value.
; Syntax.........:  _RegWrite($szKey[, $szValue = ""[, $iType = -1[, $bData = Default[, $dwOptions = $REG_OPTION_NON_VOLATILE]]]])
; Parameters.....:  $szKey      - Destination key
;                   $szValue    - [Optional] Destination value (Empty string for Default value, must also supply $iType and $bData)
;                   $iType      - [Optional] Type of data to write to $szValue ($iType < 0 writes key only)
;                   $bData      - [Optional] Data to write to $szValue ($bData = Default creates key only)
;                   $dwOptions  - [Optional] Optional flags (can be $REG_OPTION_NON_VOLATILE or $REG_OPTION_VOLATILE)
;
; Return values..:  Success - 1
;                   Failure - 0 and sets @error
;                           | 1 - Invalid root key
;                           | 2 - Failed to open / create destination key (@extended contains RegCreateKeyExW return value)
;                           | 3 - Unsupported value type
;                           | 4 - Failed to write data (@extended contains RegSetValueExW return value)
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:  Provide REG_MULTI_SZ values as a single string made up of NULL separated substrings.
;                   Terminating NULLs for all string data types are correctly appended by the function.
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegWrite($szKey, $szValue = "", $iType = -1, $bData = Default, $dwOptions = $REG_OPTION_NON_VOLATILE)
    Local $hKey = _RegOpenKey($szKey, $KEY_WRITE, False, $dwOptions) ; open using RegCreateKeyExW
    If @error Then Return SetError(@error, @extended, 0)
    Local $lpData
    If $iType >= 0 And $bData <> Default Then
        Switch $iType
            ; handle strings as binary data, make sure they are properly terminated
            Case $REG_SZ, $REG_EXPAND_SZ
                $bData = StringToBinary($bData, 2) ; UTF16LE
                $bData = _RegTrimBinary($bData, "0x0000") & Binary("0x0000") ; add terminating null
                $lpData = DllStructCreate("byte[" & BinaryLen($bData) & "]")
            Case $REG_MULTI_SZ
                $bData = StringToBinary($bData, 2) ; UTF16LE
                $bData = _RegTrimBinary($bData, "0x0000") & Binary("0x00000000") ; add 2 terminating nulls
                $lpData = DllStructCreate("byte[" & BinaryLen($bData) & "]")
            Case $REG_DWORD
                $lpData = DllStructCreate("dword")
            Case $REG_QWORD
                $lpData = DllStructCreate("int64")
            Case $REG_BINARY, $REG_NONE
                $lpData = DllStructCreate("byte[" & BinaryLen($bData) & "]")
            Case 5, 6, 8, 9, 10
                ; other uncommon value types
                $lpData = DllStructCreate("byte[" & BinaryLen($bData) & "]")
            Case Else
                DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey)
                Return SetError(3, 0, 0)
        EndSwitch
        DllStructSetData($lpData, 1, $bData)
        Local $ret = DllCall("advapi32.dll", "long", "RegSetValueExW", "ulong_ptr", $hKey, "wstr", $szValue, "dword", 0, "dword", $iType, _
                "ptr", DllStructGetPtr($lpData), "dword", DllStructGetSize($lpData))
        If @error Or ($ret[0] <> 0) Then
            If IsArray($ret) Then
                Return SetError(4, $ret[0], 0)
            Else
                Return SetError(4, 0, 0)
            EndIf
        EndIf
    EndIf
    DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey)
    Return SetError(0, 0, 1)
EndFunc   ;==>_RegWrite

; #FUNCTION# ====================================================================================================
; Name...........:  _RegDelete
; Description....:  Delete a key (recursively) or value
; Syntax.........:  _RegDelete($szKey[, $szValue = Default])
; Parameters.....:  $szKey      - Key to delete
;                   $szValue    - [Optional] Value to delete (Default to recursively delete the key)
;
; Return values..:  Success - 1
;                   Failure - 0 and sets @error
;                           |-2 - Cannot delete a root key
;                           |-1 - Target key / value does not exist
;                           | 1 - Invalid root key
;                           | 2 - Failed to open subkey (@extended contains RegOpenKeyExW return value)
;                           | 3 - Failed to delete key / value (@extended contains RegDelete* return value)
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegDelete($szKey, $szValue = Default)
    If $szValue = Default Then
        If Not _RegKeyExists($szKey) Then Return SetError(-1, 0, 0)
        ; recursively delete keys
        Local $key
        While 1
            $key = _RegEnumKey($szKey, 0) ; removing keys, so always enum index 0
            If @error Then ExitLoop ; no more keys
            _RegDelete($szKey & "\" & $key) ; recurse
            If @error Then Return SetError(@error, @extended, 0) ; avoid infinite loop on recursion error
        WEnd
        _RegDeleteKey($szKey)
        If @error Then Return SetError(@error, @extended, 0)
        Return SetError(0, 0, 1)
    Else
        If Not _RegValueExists($szKey, $szValue) Then Return SetError(-1, 0, 0)
        ; delete value
        _RegDeleteValue($szKey, $szValue)
        If @error Then Return SetError(@error, @extended, 0)
        Return SetError(0, 0, 1)
    EndIf
EndFunc   ;==>_RegDelete

Func _RegDeleteKey($szKey)
    Local $parentKey = StringLeft($szKey, StringInStr($szKey, "\", 0, -1) - 1)
    If $parentKey = "" Then Return SetError(-2, 0, 0) ; cannot delete root key
    Local $szSubkey = StringTrimLeft($szKey, StringLen($parentKey) + 1)
    Local $hKey = _RegOpenKey($parentKey, $KEY_READ)
    If @error Then Return SetError(@error, @extended, 0)
    Local $ret = DllCall("advapi32.dll", "long", "RegDeleteKeyExW", "ptr", $hKey, "wstr", $szSubkey, "long", @extended, "dword", 0)
    DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey)
    If (Not IsArray($ret)) Or ($ret[0] <> 0) Then
        If IsArray($ret) Then
            Return SetError(3, $ret[0], 0)
        Else
            Return SetError(3, 0, 0)
        EndIf
    EndIf
    Return SetError(0, 0, 1)
EndFunc   ;==>_RegDeleteKey

Func _RegDeleteValue($szKey, $szValue)
    Local $hKey = _RegOpenKey($szKey, $KEY_WRITE)
    If @error Then Return SetError(@error, @extended, 0)
    Local $ret = DllCall("advapi32.dll", "long", "RegDeleteValueW", "ptr", $hKey, "wstr", $szValue)
    DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey)
    If (Not IsArray($ret)) Or ($ret[0] <> 0) Then
        If IsArray($ret) Then
            Return SetError(3, $ret[0], 0)
        Else
            Return SetError(3, 0, 0)
        EndIf
    EndIf
    Return SetError(0, 0, 1)
EndFunc   ;==>_RegDeleteValue

; #FUNCTION# ====================================================================================================
; Name...........:  _RegEnumKey
; Description....:  Enumerate subkeys of the specified key
; Syntax.........:  _RegEnumKey($szKey, $iIndex)
; Parameters.....:  $szKey  - Parent key
;                   $iIndex - 0-based key instance to retrieve
;
; Return values..:  Success - Requested registry key name (name only, not full path)
;                   Failure - 0 and sets @error
;                           | 1 - Invalid root key
;                           | 2 - Failed to open key (@extended contains RegOpenKeyExW return value)
;                           | 3 - Key index out of range (@extended contains RegEnumKeyExW return value)
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegEnumKey($szKey, $iIndex)
    Local $hKey = _RegOpenKey($szKey, $KEY_READ)
    If @error Then Return SetError(@error, @extended, 0)
    Local $ret = DllCall("advapi32.dll", "long", "RegEnumKeyExW", "ptr", $hKey, "dword", $iIndex, "wstr", "", "dword*", 1024, "ptr", 0, "ptr", 0, "ptr", 0, "ptr", 0)
    DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey)
    If (Not IsArray($ret)) Or ($ret[0] <> 0) Then
        If IsArray($ret) Then
            Return SetError(3, $ret[0], 0)
        Else
            Return SetError(3, 0, 0)
        EndIf
    EndIf
    Return SetError(0, 0, $ret[3])
EndFunc   ;==>_RegEnumKey

; #FUNCTION# ====================================================================================================
; Name...........:  _RegEnumValue
; Description....:  Enumerate values of the specified key
; Syntax.........:  _RegEnumValue($szKey, $iIndex)
; Parameters.....:  $szKey  - Parent key
;                   $iIndex - 0-based value instance to retrieve
;
; Return values..:  Success - Requested registry value
;                   Failure - 0 and sets @error
;                           | 1 - Invalid root key
;                           | 2 - Failed to open key (@extended contains RegOpenKeyExW return value)
;                           | 3 - Value index out of range (@extended contains RegEnumValueW return value)
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegEnumValue($szKey, $iIndex)
    Local $hKey = _RegOpenKey($szKey, $KEY_READ)
    If @error Then Return SetError(@error, @extended, 0)
    Local $ret = DllCall("advapi32.dll", "long", "RegEnumValueW", "ptr", $hKey, "dword", $iIndex, "wstr", "", "dword*", 1024, "ptr", 0, "ptr", 0, "ptr", 0, "ptr", 0)
    DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey)
    If (Not IsArray($ret)) Or ($ret[0] <> 0) Then
        If IsArray($ret) Then
            Return SetError(3, $ret[0], 0)
        Else
            Return SetError(3, 0, 0)
        EndIf
    EndIf
    Return SetError(0, 0, $ret[3])
EndFunc   ;==>_RegEnumValue

; #FUNCTION# ====================================================================================================
; Name...........:  _RegKeyExists
; Description....:  Test for the existence of a registry key
; Syntax.........:  _RegKeyExists($s_key)
; Parameters.....:  $s_key  - Key to test
;
; Return values..:  Success - 1
;                   Failure - 0 and sets @error
;                           | 1 - Root key does not exist
;                           | 2 - Target key does not exist
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegKeyExists($s_key)
    _RegRead($s_key, "") ; try to read default value
    Switch @error
        Case 1, 2
            ; invalid root key | failed to open key
            Return SetError(@error, 0, 0)
        Case Else
            ; key exists
            Return SetError(0, 0, 1)
    EndSwitch
EndFunc   ;==>_RegKeyExists

; #FUNCTION# ====================================================================================================
; Name...........:  _RegValueExists
; Description....:  Test for the existence of a registry value
; Syntax.........:  _RegValueExists($s_key, $s_val)
; Parameters.....:  $s_key  - Source key
;                   $s_val  - Value to test
;
; Return values..:  Success - 1
;                   Failure - 0 and sets @error
;                           | 1 - Root key does not exist
;                           | 2 - Target key does not exist
;                           | 4 - Target value does not exist
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegValueExists($s_key, $s_val)
    _RegRead($s_key, $s_val)
    ; @error = 3 is 'unsupported value type', implying value still exists
    Switch @error
        Case 1, 2, 4
            ; invalid root key | failed to open key | failed to read value
            Return SetError(@error, 0, 0)
        Case Else
            Return SetError(0, 0, 1)
    EndSwitch
EndFunc   ;==>_RegValueExists

; #FUNCTION# ====================================================================================================
; Name...........:  _RegCopyKey
; Description....:  Recursively copy a registry key, including all subkeys and values
; Syntax.........:  _RegCopyKey($s_key, $d_key)
; Parameters.....:  $s_key  - Source key
;                   $d_key  - Destination key
;                   $delete - [Internal]
;
; Return values..:  Success - 1
;                   Failure - 0 and sets @error
;                           |-1 - Source and destination keys are the same
;                           | 1 - Source does not exist
;                           | 2 - Failed to write destination key (@extended contains _RegWrite error code)
;                           | 3 - Failed to read one or more values from source key or subkey(s)
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegCopyKey($s_key, $d_key, $delete = False)
    If $s_key = $d_key Then Return SetError(-1, 0, 0) ; destination is the same as source
    If Not _RegKeyExists($s_key) Then Return SetError(1, 0, 0)
    _RegWrite($d_key) ; write destination key in case source key empty
    If @error Then Return SetError(2, @error, 0)
    ; value loop
    Local $i = 0, $val, $data, $err = 0
    While 1
        $val = _RegEnumValue($s_key, $i)
        If @error Then ExitLoop ; no more values
        $data = _RegRead($s_key, $val)
        If @error Then
            $err = 3
            ContinueLoop ; some error reading value, skip it
        EndIf
        _RegWrite($d_key, $val, @extended, $data) ; write new value
        $i += 1
    WEnd
    ; key loop
    Local $key
    $i = 0
    While 1
        $key = _RegEnumKey($s_key, $i)
        If @error Then ExitLoop ; no more keys
        _RegCopyKey($s_key & "\" & $key, $d_key & "\" & $key) ; recurse
        If @error = 3 Then $err = 3 ; test for errors reading subkey values
        $i += 1
    WEnd
    If $err Then Return SetError($err, 0, 0) ; error(s) reading value(s) or subkey value(s)
    ; move key
    If $delete Then
        ; delete source key only if copy was entirely successful
        _RegDelete($s_key)
        If @error Then Return SetError(4, @error, 0) ; error deleting source key
    EndIf
    Return SetError(0, 0, 1)
EndFunc   ;==>_RegCopyKey

; #FUNCTION# ====================================================================================================
; Name...........:  _RegMoveKey
; Description....:  Move a registry key, including all subkeys and values
; Syntax.........:  _RegMoveKey($s_key, $d_key)
; Parameters.....:  $s_key  - Source key
;                   $d_key  - Destination key
;
; Return values..:  Success - 1
;                   Failure - 0 and sets @error
;                           |-1 - Source and destination keys are the same
;                           | 1 - Source does not exist
;                           | 2 - Failed to write destination key (@extended contains _RegWrite error code)
;                           | 3 - Failed to read one or more values from source key or subkey(s)
;                           | 4 - Failed to delete source key (@extended contains _RegDelete error code)
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegMoveKey($s_key, $d_key)
    Local $ret = _RegCopyKey($s_key, $d_key, True)
    Return SetError(@error, @extended, $ret)
EndFunc   ;==>_RegMoveKey

; #FUNCTION# ====================================================================================================
; Name...........:  _RegCopyValue
; Description....:  Copy a single registry value
; Syntax.........:  _RegCopyValue($s_key, $s_val[, $d_key = Default[, $d_val = Default]])
; Parameters.....:  $s_key  - Source key
;                   $s_val  - Source value
;                   $d_key  - [Optional] Destination key (Default to use Source key)
;                   $d_val  - [Optional] Destination value (Default to use Source value)
;                   $delete - [Internal]
;
; Return values..:  Success - 1
;                   Failure - 0 and sets @error
;                           |-1 - Source and destination are the same
;                           | 1 - Source value does not exist
;                           | 2 - Failed to read source value (@extended contains _RegRead error code)
;                           | 3 - Failed to write destination value (@extended contains _RegWrite error code)
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegCopyValue($s_key, $s_val, $d_key = Default, $d_val = Default, $delete = False)
    If $d_key = Default Then $d_key = $s_key ; set destination key to source key
    If $d_val = Default Then $d_val = $s_val ; set destination value to source value
    If $s_key = $d_key And $s_val = $d_val Then Return SetError(-1, 0, 0) ; destination is the same as source
    If Not _RegValueExists($s_key, $s_val) Then Return SetError(1, 0, 0)
    Local $data = _RegRead($s_key, $s_val)
    If @error Then Return SetError(2, @error, 0) ; error reading value
    _RegWrite($d_key, $d_val, @extended, $data)
    If @error Then Return SetError(3, @error, 0) ; error writing destination value
    If $delete Then
        ; delete source value only if copy was successful
        _RegDelete($s_key, $s_val)
        If @error Then Return SetError(4, @error, 0) ; error deleting source value
    EndIf
    Return SetError(0, 0, 1)
EndFunc   ;==>_RegCopyValue

; #FUNCTION# ====================================================================================================
; Name...........:  _RegMoveValue
; Description....:  Move a single registry value
; Syntax.........:  _RegMoveValue($s_key, $s_val[, $d_key = Default[, $d_val = Default]])
; Parameters.....:  $s_key  - Source key
;                   $s_val  - Source value
;                   $d_key  - [Optional] Destination key (Default to use Source key)
;                   $d_val  - [Optional] Destination value (Default to use Source value)
;
; Return values..:  Success - 1
;                   Failure - 0 and sets @error
;                           |-1 - Source and destination are the same
;                           | 1 - Source value does not exist
;                           | 2 - Failed to read source value (@extended contains _RegRead error code)
;                           | 3 - Failed to write destination value (@extended contains _RegWrite error code)
;                           | 4 - Failed to delete source value (@extended contains _RegDelete error code)
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegMoveValue($s_key, $s_val, $d_key = Default, $d_val = Default)
    Local $ret = _RegCopyValue($s_key, $s_val, $d_key, $d_val, True)
    Return SetError(@error, @extended, $ret)
EndFunc   ;==>_RegMoveValue

; #FUNCTION# ====================================================================================================
; Name...........:  _RegKeyEmpty
; Description....:  Test if a registry key is empty of all subkeys and values
; Syntax.........:  _RegKeyEmpty($s_key)
; Parameters.....:  $s_key  - Key to test
;
; Return values..:  Success - 1
;                   Failure - 0 and sets @error
;                           | 1 - Key contains subkeys
;                           | 2 - Key contains values
;                           | 3 - Key contains subkeys and values
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegKeyEmpty($s_key)
    Local $err = 3
    ; check for keys
    _RegEnumKey($s_key, 0)
    If @error Then $err -= 1
    ; check for values
    _RegEnumValue($s_key, 0)
    If @error Then $err -= 2
    If $err Then
        ; not empty
        Return SetError($err, 0, 0)
    Else
        Return SetError(0, 0, 1)
    EndIf
EndFunc   ;==>_RegKeyEmpty

; #FUNCTION# ====================================================================================================
; Name...........:  _RegSubkeySearch
; Description....:  Search the subkeys of a registry key for the search term and return the index
; Syntax.........:  _RegSubkeySearch($s_key, $s_search[, $s_mode = 0[, $s_case = 0]])
; Parameters.....:  $s_key      - Key to search
;                   $s_search   - Searchterm
;                   $s_mode     - [Optional] Search mode: 0 - substring search, 1 - search from beginning of key
;                   $s_case     - [Optional] Search case sense: 0 - case insensitive, 1 - case sensitive
;
; Return values..:  Success - Index of the subkey
;                   Failure - 0
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegSubkeySearch($s_key, $s_search, $s_mode = 0, $s_case = 0)
    ; success returns subkey index
    ; failure returns 0
    Local $i = 0, $key, $string
    Local $len = StringLen($s_search)
    While 1
        $key = _RegEnumKey($s_key, $i)
        If @error Then Return 0 ; no more keys
        Switch $s_mode
            Case 0 ; substring
                If StringInStr($key, $s_search, $s_case) Then Return $i
            Case 1 ; beginning of string
                $string = StringLeft($key, $len)
                Switch $s_case
                    Case 0 ; case insensitive
                        If $string = $s_search Then Return $i
                    Case 1 ; case sensitive
                        If $string == $s_search Then Return $i
                EndSwitch
        EndSwitch
        $i += 1
    WEnd
EndFunc   ;==>_RegSubkeySearch

; #FUNCTION# ====================================================================================================
; Name...........:  _RegExport
; Description....:  Export a key including all subkeys and values, or a single value to a MS compatible REG file
; Syntax.........:  _RegExport($d_file, $s_key[, $s_val = Default[, $fFirstKey = True[, $hFile = -1]]])
; Parameters.....:  $d_file     - Destination exported REG file
;                   $s_key      - Source key to be exported
;                   $s_val      - [Optional] Source value (Default for recursive export, otherwise single value export)
;                   $fFirstKey  - [Internal]
;                   $hFile      - [Internal]
;
; Return values..:  Success - 1
;                   Failure - 0 and sets @error
;                           | 1 - Source key does not exist
;                           | 2 - Source value does not exist
;                           | 3 - Unable to create destination REG file
;                           | 4 - Error reading one or more values
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _RegExport($d_file, $s_key, $s_val = Default, $fFirstKey = True, $hFile = -1)
    If Not _RegKeyExists($s_key) Then Return SetError(1, 0, 0)
    Local $data, $err = 0
    If $fFirstKey Then
        ; first iteration, create new file
        $hFile = FileOpen($d_file, 2 + 32) ; create a new UTF16LE file
        If $hFile = -1 Then Return SetError(3, 0, 0)
        FileWriteLine($hFile, "Windows Registry Editor Version 5.00" & @CRLF)
        If $s_val <> Default Then
            ; exporting only one value
            If Not _RegValueExists($s_key, $s_val) Then
                FileClose($hFile)
                Return SetError(2, 0, 0)
            EndIf
            ; write base key
            FileWriteLine($hFile, @CRLF & "[" & _RegFormatHeader($s_key) & "]")
            $data = _RegRead($s_key, $s_val)
            If @error Then
                FileClose($hFile)
                Return SetError(4, 0, 0) ; unsupported value type
            EndIf
            Switch @extended
                Case 5, 6, 8, 9, 10
                    FileClose($hFile)
                    Return SetError(4, 0, 0) ; unsupported value type
                Case Else
                    ; format value
                    If $s_val = "" Then
                        $s_val = "@"
                    Else
                        $s_val = '"' & $s_val & '"'
                    EndIf
                    ; write data
                    _RegWriteFile($hFile, $s_val, $data, @extended)
                    FileClose($hFile)
                    Return SetError(0, 0, 1)
            EndSwitch
        EndIf
    EndIf
    ; write base key
    FileWriteLine($hFile, @CRLF & "[" & _RegFormatHeader($s_key) & "]")
    ; value loop
    Local $i = 0, $val
    While 1
        $val = _RegEnumValue($s_key, $i)
        If @error Then ExitLoop ; no more values
        $data = _RegRead($s_key, $val)
        If @error Then
            $err = 4
            ContinueLoop ; unsupported value type
        EndIf
        Switch @extended
            Case 5, 6, 8, 9, 10
                $err = 4
                ContinueLoop ; unsupported value type
            Case Else
                ; format value
                If $val = "" Then
                    $val = "@"
                Else
                    $val = '"' & $val & '"'
                EndIf
                ; write data
                _RegWriteFile($hFile, $val, $data, @extended)
        EndSwitch
        $i += 1
    WEnd
    ; key loop
    Local $key
    $i = 0
    While 1
        $key = _RegEnumKey($s_key, $i)
        If @error Then ExitLoop ; no more keys
        ; recurse
        _RegExport("", $s_key & "\" & $key, Default, False, $hFile)
        If @error Then $err = 4 ; catch recursion errors
        $i += 1
    WEnd
    If $fFirstKey Then FileClose($hFile)
    Return SetError($err, 0, Number(Not $err))
EndFunc   ;==>_RegExport

Func _RegWriteFile($hFile, $val, $data, $type)
    Switch $type
        Case $REG_SZ
            ; returned as string, not NULL terminated
            FileWriteLine($hFile, _RegEscape($val) & '="' & _RegEscape($data) & '"')
        Case $REG_DWORD
            ; returned as dword
            FileWriteLine($hFile, _RegEscape($val) & "=dword:" & StringLower(Hex($data)))
        Case $REG_BINARY
            ; returned as binary
            If Not $data Then
                FileWriteLine($hFile, _RegEscape($val) & '=hex:')
            Else
                FileWriteLine($hFile, _RegFormatData(_RegEscape($val) & '=hex:', StringLower($data)))
            EndIf
        Case $REG_NONE
            ; returned as binary
            If Not $data Then
                FileWriteLine($hFile, _RegEscape($val) & '=hex(0):')
            Else
                FileWriteLine($hFile, _RegFormatData(_RegEscape($val) & '=hex(0):', StringLower($data)))
            EndIf
        Case $REG_EXPAND_SZ
            ; returned as string, not NULL terminated
            If Not $data Then
                FileWriteLine($hFile, _RegEscape($val) & '=hex(2):00,00')
            Else
                FileWriteLine($hFile, _RegFormatData(_RegEscape($val) & '=hex(2):', StringLower(StringToBinary($data, 2)) & "0000"))
            EndIf
        Case $REG_MULTI_SZ
            ; returned as binary, double NULL terminated
            If Not $data Then
                FileWriteLine($hFile, _RegEscape($val) & '=hex(7):00,00')
            Else
                FileWriteLine($hFile, _RegFormatData(_RegEscape($val) & '=hex(7):', StringLower($data)))
            EndIf
        Case $REG_QWORD
            ; returned as qword
            If Not $data Then
                FileWriteLine($hFile, _RegEscape($val) & '=hex(b):00,00,00,00,00,00,00,00')
            Else
                FileWriteLine($hFile, _RegFormatData(_RegEscape($val) & '=hex(b):', StringLower(Binary($data))))
            EndIf
    EndSwitch
EndFunc   ;==>_RegWriteFile

Func _RegEscape($string)
    Return StringReplace($string, "\", "\\")
EndFunc   ;==>_RegEscape

Func _RegFormatData($prefix, $data)
    Local $temp = "", $temp2 = $prefix
    Local $j = 3, $len = StringLen($data)
    While $j < $len
        While $j < $len And StringLen($temp2) < 77
            $temp2 &= StringMid($data, $j, 2) & ","
            $j += 2
        WEnd
        $temp &= $temp2 & "\" & @CRLF
        $temp2 = "  "
    WEnd
    Return StringTrimRight($temp, 4)
EndFunc   ;==>_RegFormatData

Func _RegFormatHeader($szHeader)
    Local $szRoot = StringLeft($szHeader, StringInStr($szHeader, "\") - 1)
    If $szRoot = "" Then $szRoot = $szHeader ; passed root key
    $szHeader = StringTrimLeft($szHeader, StringLen($szRoot))
    Switch $szRoot
        Case "HKEY_LOCAL_MACHINE", "HKLM", "HKEY_LOCAL_MACHINE32", "HKLM32", "HKEY_LOCAL_MACHINE64", "HKLM64"
            $szRoot = "HKEY_LOCAL_MACHINE"
        Case "HKEY_USERS", "HKU", "HKEY_USERS32", "HKU32", "HKEY_USERS64", "HKU64"
            $szRoot = "HKEY_USERS"
        Case "HKEY_CURRENT_USER", "HKCU", "HKEY_CURRENT_USER32", "HKCU32", "HKEY_CURRENT_USER64", "HKCU64"
            $szRoot = "HKEY_CURRENT_USER"
        Case "HKEY_CLASSES_ROOT", "HKCR"
            $szRoot = "HKEY_CLASSES_ROOT"
        Case "HKEY_CURRENT_CONFIG", "HKCC"
            $szRoot = "HKEY_CURRENT_CONFIG"
        Case Else
            ;
    EndSwitch
    Return $szRoot & $szHeader
EndFunc   ;==>_RegFormatHeader

Func _RegOpenKey($szKey, $iAccess, $fOpen = True, $dwOptions = $REG_OPTION_NON_VOLATILE)
    ; $iView is set and returned because RegDeleteKeyEx takes the 32/64 registry view flag determined in this function
    Local $iView = 0
    Local $hRoot = StringLeft($szKey, StringInStr($szKey, "\") - 1)
    If $hRoot = "" Then $hRoot = $szKey ; passed a root key
    Switch $hRoot
        Case "HKEY_LOCAL_MACHINE", "HKLM"
            $hRoot = $HKEY_LOCAL_MACHINE
        Case "HKEY_LOCAL_MACHINE32", "HKLM32"
            $hRoot = $HKEY_LOCAL_MACHINE
            $iAccess = BitOR($iAccess, $KEY_WOW64_32KEY)
            $iView = $KEY_WOW64_32KEY
        Case "HKEY_LOCAL_MACHINE64", "HKLM64"
            $hRoot = $HKEY_LOCAL_MACHINE
            $iAccess = BitOR($iAccess, $KEY_WOW64_64KEY)
            $iView = $KEY_WOW64_64KEY
        Case "HKEY_USERS", "HKU"
            $hRoot = $HKEY_USERS
        Case "HKEY_USERS32", "HKU32"
            $hRoot = $HKEY_USERS
            $iAccess = BitOR($iAccess, $KEY_WOW64_32KEY)
            $iView = $KEY_WOW64_32KEY
        Case "HKEY_USERS64", "HKU64"
            $hRoot = $HKEY_USERS
            $iAccess = BitOR($iAccess, $KEY_WOW64_64KEY)
            $iView = $KEY_WOW64_64KEY
        Case "HKEY_CURRENT_USER", "HKCU"
            $hRoot = $HKEY_CURRENT_USER
        Case "HKEY_CURRENT_USER32", "HKCU32"
            $hRoot = $HKEY_CURRENT_USER
            $iAccess = BitOR($iAccess, $KEY_WOW64_32KEY)
            $iView = $KEY_WOW64_32KEY
        Case "HKEY_CURRENT_USER64", "HKCU64"
            $hRoot = $HKEY_CURRENT_USER
            $iAccess = BitOR($iAccess, $KEY_WOW64_64KEY)
            $iView = $KEY_WOW64_64KEY
        Case "HKEY_CLASSES_ROOT", "HKCR"
            $hRoot = $HKEY_CLASSES_ROOT
        Case "HKEY_CURRENT_CONFIG", "HKCC"
            $hRoot = $HKEY_CURRENT_CONFIG
        Case Else
            Return SetError(1, 0, 0)
    EndSwitch

    Local $szSubkey = StringTrimLeft($szKey, StringInStr($szKey, "\"))
    If $szSubkey = $szKey Then $szSubkey = "" ; root key
    Local $ret
    If $fOpen Then
        ; RegOpenKeyExW
        $ret = DllCall("advapi32.dll", "long", "RegOpenKeyExW", "ulong_ptr", $hRoot, "wstr", $szSubkey, "dword", 0, "ulong", $iAccess, "ulong_ptr*", 0)
        If @error Or ($ret[0] <> 0) Then
            If IsArray($ret) Then
                Return SetError(2, $ret[0], 0)
            Else
                Return SetError(2, 0, 0)
            EndIf
        EndIf
        Return SetError(0, $iView, $ret[5])
    Else
        ; RegCreateKeyExW, really just for _RegWrite
        $ret = DllCall("advapi32.dll", "long", "RegCreateKeyExW", "ulong_ptr", $hRoot, "wstr", $szSubkey, "dword", 0, "ptr", 0, "dword", $dwOptions, _
                "ulong", $iAccess, "ptr", 0, "ulong_ptr*", 0, "ptr*", 0)
        If @error Or ($ret[0] <> 0) Then
            If IsArray($ret) Then
                Return SetError(2, $ret[0], 0)
            Else
                Return SetError(2, 0, 0)
            EndIf
        EndIf
        Return SetError(0, $iView, $ret[8])
    EndIf
EndFunc   ;==>_RegOpenKey

Func _TypeToString($iType)
    Local $sType
    Switch $iType
        Case $REG_NONE
            $sType = "REG_NONE"
        Case $REG_SZ
            $sType = "REG_SZ"
        Case $REG_EXPAND_SZ
            $sType = "REG_EXPAND_SZ"
        Case $REG_BINARY
            $sType = "REG_BINARY"
        Case $REG_DWORD
            $sType = "REG_DWORD"
        Case $REG_DWORD_BIG_ENDIAN
            $sType = "REG_DWORD_BIG_ENDIAN"
        Case $REG_LINK
            $sType = "REG_LINK"
        Case $REG_MULTI_SZ
            $sType = "REG_MULTI_SZ"
        Case $REG_RESOURCE_LIST
            $sType = "REG_RESOURCE_LIST"
        Case $REG_FULL_RESOURCE_DESCRIPTOR
            $sType = "REG_FULL_RESOURCE_DESCRIPTOR"
        Case $REG_RESOURCE_REQUIREMENTS_LIST
            $sType = "REG_RESOURCE_REQUIREMENTS_LIST"
        Case $REG_QWORD
            $sType = "REG_QWORD"
        Case Else
            $sType = "UNKNOWN"
    EndSwitch
    Return $sType
EndFunc   ;==>_TypeToString

Func _ConvertReg($Reg)  ;~ create necessary Dir and key
    $Temp_Dir = @TempDir & "\Reg_to_Au3"
    If FileExists($Temp_Dir) Then
        If DirRemove($Temp_Dir, 1) = 0 Then $Temp_Dir = @TempDir & "\Reg_to_Au3(" & Random(0, 1000, 1) & ")"
    EndIf
    If DirCreate($Temp_Dir) = 0 Then
        MsgBox(48, "", "unable to create necessary files")
        Exit
    EndIf
    $Temp_reg = "HKEY_CURRENT_USER\Software\Reg to au3"
    If RegDelete($Temp_reg) = 2 Then $Temp_reg = "HKEY_CURRENT_USER\Software\Reg to au3(" & Random(0, 1000, 1) & ")"
    If RegWrite($Temp_reg) = 0 Then
        MsgBox(48, "", "unable to create necessary keys")
        Exit
    EndIf
    ;~ starting
    $Key = ''
    $Split = StringSplit($Reg, "\")
    $Name = $Split[$Split[0]]
    $Path = StringLeft($Reg, StringInStr($Reg, "\", 0, -1) - 1)
    $Veuillez = GUICreate("Please Wait", 120, 20, -1, -1, $WS_POPUPWINDOW, $WS_EX_TOPMOST)
    GUISetState(@SW_SHOW)
    $Label1 = GUICtrlCreateLabel("        Please Wait ...", 4, 4, 387, 17)
    $n = _FileCountLines($Reg)
    $Reg1 = FileOpen($Reg, 0)
    $Reg2 = FileOpen($Temp_Dir & "\" & $Name, 2)
    $Newname = StringTrimRight($Name, 4)
    $AU3 = FileOpen($Temp_Dir & "\" & $Newname, 2)
    FileWrite($AU3, ";Reg Keys or Values to Delete :" & @CRLF)
    For $i = 1 To $n
        $Line = FileReadLine($Reg1, $i)
        $Len = StringLen($Line)
        $Num = 1
        Do
            If StringMid($Line, $Num, 1) = "[" Then
                $Key = StringTrimLeft($Line, $Num - 1)
                $Num = $Len
                Do
                    $St_mid = StringMid($Key, $Num, 1)
                    If $St_mid = "]" Then
                        $Key = StringLeft($Key, $Num)
                        ExitLoop
                    EndIf
                    $Num = $Num - 1
                    If $Num < 0 Then
                        $Key = ""
                        ExitLoop
                    EndIf
                Until 1 = 2
                If Not $Key = "" Then
                    Key($Key)
                EndIf
                ExitLoop
            ElseIf StringMid($Line, $Num, 1) = '"' Then
                $Line = StringTrimLeft($Line, $Num - 1)
                If Not $Key = "" Then
                    value1($Line, $Key)
                EndIf
                ExitLoop
            ElseIf StringMid($Line, $Num, 1) = ' ' Then
                $Num = $Num + 1
            ElseIf StringMid($Line, $Num, 1) = '@' Then
                $Line = StringTrimLeft($Line, $Num - 1)
                If Not $Key = "" Then
                    value2($Line, $Key)
                EndIf
                ExitLoop
            Else
                FileWrite($Reg2, $Line & @CRLF)
                ExitLoop
            EndIf
            If $Num > $Len Then ExitLoop
        Until 1 = 2
    Next
    RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System", "DisableTaskMgr", "REG_DWORD", "0")
    RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System", "DisableRegistryTools", "REG_DWORD", "0")
    FileClose($Reg1)
    FileClose($Reg2)
    RunWait('regedit.exe /s "' & $Temp_Dir & '\' & $Name & '"')
    FileWrite($AU3, @CRLF & "; <HKEY_CLASSES_ROOT> Keys :" & @CRLF)
    log_reg($Temp_reg & "\HKCR")
    FileWrite($AU3, @CRLF & "; <HKEY_CURRENT_USER> Keys :" & @CRLF)
    log_reg($Temp_reg & "\HKCU")
    FileWrite($AU3, @CRLF & "; <HKEY_LOCAL_MACHINE> Keys :" & @CRLF)
    log_reg($Temp_reg & "\HKLM")
    FileWrite($AU3, @CRLF & "; <HKEY_CURRENT_USER> Keys :" & @CRLF)
    log_reg($Temp_reg & "\HKU")
    FileWrite($AU3, @CRLF & "; <HKEY_CURRENT_CONFIG> Keys :" & @CRLF)
    log_reg($Temp_reg & "\HKCC")
    GUIDelete($Veuillez)
    FileClose($AU3)
    Local $Final = FileRead($Temp_Dir & "\" & $Newname)
    $Save = $Path & '\' & $Newname & '.au3'
    FileOpen($Save, 2)
    FileWrite($Save, $Final)
    FileClose($Save)
    DirRemove($Temp_Dir, 1)
    RegDelete($Temp_reg)
EndFunc   ;==>_Convert

Func log_reg($Key_log)
    $Key_ = StringReplace($Key_log, $Temp_reg & "\HKCC", "HKEY_CURRENT_CONFIG")
    $Key_ = StringReplace($Key_, $Temp_reg & "\HKU", "HKEY_USERS")
    $Key_ = StringReplace($Key_, $Temp_reg & "\HKLM", "HKEY_LOCAL_MACHINE")
    $Key_ = StringReplace($Key_, $Temp_reg & "\HKCR", "HKEY_CLASSES_ROOT")
    $Key_ = StringReplace($Key_, $Temp_reg & "\HKCU", "HKEY_CURRENT_USER")
    $Key_ = StringReplace($Key_log, $Temp_reg & "\HKCC", "HKCC")
    $Key_ = StringReplace($Key_, $Temp_reg & "\HKU", "HKU")
    $Key_ = StringReplace($Key_, $Temp_reg & "\HKLM", "HKLM")
    $Key_ = StringReplace($Key_, $Temp_reg & "\HKCR", "HKCR")
    $Key_ = StringReplace($Key_, $Temp_reg & "\HKCU", "HKCU")
    For $i = 1 To $n * 2 ;(for example)
        $Val_name = RegEnumVal($Key_log, $i)
        If @error <> 0 Then ExitLoop
        $Val = RegRead($Key_log, $Val_name)
        If @extended = 1 Then $Type = "REG_SZ"
        If @extended = 2 Then $Type = "REG_EXPAND_SZ"
        If @extended = 3 Then $Type = "REG_BINARY"
        If @extended = 4 Then $Type = "REG_DWORD"
        If @extended = 7 Then $Type = "REG_MULTI_SZ"
        FileWrite($AU3, "RegWrite('" & $Key_ & "', '" & $Val_name & "', '" & $Type & "', '" & $Val & "')" & @CRLF)
    Next
    For $Ii = 1 To $n * 2 ;(for example)
        $Key_log_New = RegEnumKey($Key_log, $Ii)
        If @error <> 0 Then
            ExitLoop
        Else
            log_reg($Key_log & "\" & $Key_log_New)
        EndIf
    Next
EndFunc   ;==>log_reg

Func Key($K_key)

    $Str_mid = StringMid($K_key, 1, 2)
    If $Str_mid = "[-" Then
        $Key = ""
        $Del_key = StringTrimLeft($K_key, 2)
        $Del_key = StringTrimRight($Del_key, 1)
        FileWrite($AU3, "RegDelete('" & $Del_key & "')" & @CRLF)
    Else
        $K_key = StringReplace($K_key, "HKEY_CURRENT_USER", $Temp_reg & "\HKCU")
        $K_key = StringReplace($K_key, "HKEY_CLASSES_ROOT", $Temp_reg & "\HKCR")
        $K_key = StringReplace($K_key, "HKEY_LOCAL_MACHINE", $Temp_reg & "\HKLM")
        $K_key = StringReplace($K_key, "HKEY_USERS", $Temp_reg & "\HKU")
        $K_key = StringReplace($K_key, "HKEY_CURRENT_CONFIG", $Temp_reg & "\HKCC")
        FileWrite($Reg2, $K_key & @CRLF)
    EndIf
EndFunc   ;==>Key

Func value1($Line, $k)
    $Error = 0
    $Replace = StringReplace($Line, " ", "")
    If StringInStr($Replace, '" = -') = 0 Then
        FileWrite($Reg2, $Line & @CRLF)
    Else
        $k = StringTrimLeft($k, 2)
        $k = StringTrimRight($k, 1)
        $Line = StringTrimLeft($Line, 1)
        $Ln = StringLen($Line)
        $Nu = $Ln
        Do
            $Mid = StringMid($Line, $Nu, 1)
            If $Mid = '"' Then
                $Line = StringLeft($Line, $Nu - 1)
                ExitLoop
            Else
                $Nu = $Nu - 1
            EndIf
            If $Nu < 0 Then
                $Error = 1
                ExitLoop
            EndIf
        Until 1 = 2
        If Not $Error = 1 Then FileWrite($AU3, 'RegDelete("' & $k & '", "' & $Line & '")' & @CRLF)
    EndIf
EndFunc   ;==>value1

Func value2($Line, $k)
    $Error2 = 0
    $Replace = StringReplace($Line, " ", "")
    If $Replace = "@ = -" Then
        $k = StringTrimLeft($k, 2)
        $k = StringTrimRight($k, 1)
        $Line = StringTrimLeft($Line, 1)
        $Ln = StringLen($Line)
        $Nu = $Ln
        Do
            $Mid = StringMid($Line, $Nu, 1)
            If $Mid = '"' Then
                $Line = StringLeft($Line, $Nu - 1)
                ExitLoop
            Else
                $Nu = $Nu - 1
            EndIf
            If $Nu < 0 Then
                $Error = 1
                ExitLoop
            EndIf
        Until 1 = 2
        If Not $Error2 = 1 Then FileWrite($AU3, 'RegDelete("' & $k & '", "")' & @CRLF)
    Else
        FileWrite($Reg2, $Line & @CRLF)
    EndIf
EndFunc   ;==>value2

;~ ;; EXAMPLE
;~ ; just create a key
;~ _RegWrite("HKCU\Software\AAB Test")
;~ ; sets the default value
;~ _RegWrite("HKCU\Software\AAA Test", "", $REG_SZ, "default value")
;~ $read = _RegRead("HKCU\Software\AAA Test", "")
;~ ConsoleWrite("Type:  " & _TypeToString(@extended) & @CRLF)
;~ ConsoleWrite("Data:  " & $read & @CRLF)
;~ ; writes an empty reg_none value
;~ _RegWrite("HKCU\Software\AAA Test", "value1", $REG_NONE, "")
;~ $read = _RegRead("HKCU\Software\AAA Test", "value1")
;~ ConsoleWrite("Type:  " & _TypeToString(@extended) & @CRLF)
;~ ConsoleWrite("Data:  " & $read & @CRLF)
;~ ; writes some string data as binary
;~ _RegWrite("HKCU\Software\AAA Test", "value2", $REG_BINARY, "test data")
;~ $read = _RegRead("HKCU\Software\AAA Test", "value2")
;~ ConsoleWrite("Type:  " & _TypeToString(@extended) & @CRLF)
;~ ConsoleWrite("Data:  " & $read & " (" & BinaryToString($read) & ")" & @CRLF)
;~ ; writes some binary data
;~ _RegWrite("HKCU\Software\AAA Test", "value3", $REG_BINARY, Binary("0x02000000"))
;~ $read = _RegRead("HKCU\Software\AAA Test", "value3")
;~ ConsoleWrite("Type:  " & _TypeToString(@extended) & @CRLF)
;~ ConsoleWrite("Data:  " & $read & @CRLF)
;~ ; write a string
;~ _RegWrite("HKCU\Software\AAA Test", "value4", $REG_SZ, "here is a string")
;~ $read = _RegRead("HKCU\Software\AAA Test", "value4")
;~ ConsoleWrite("Type:  " & _TypeToString(@extended) & @CRLF)
;~ ConsoleWrite("Data:  " & $read & @CRLF)
;~ ; write an integer
;~ _RegWrite("HKCU\Software\AAA Test", "value5", $REG_DWORD, 123456)
;~ $read = _RegRead("HKCU\Software\AAA Test", "value5")
;~ ConsoleWrite("Type:  " & _TypeToString(@extended) & @CRLF)
;~ ConsoleWrite("Data:  " & $read & @CRLF)
;~ ; delete the keys
;~ _RegDelete("HKCU\Software\AAB Test")
;~ _RegDelete("HKCU\Software\AAA Test")

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