This works on reg-files I exported in windows reg-file v5.00 format. but it's not finished-- that is, i think it works, but i haven't had time to test it fully, especially my regwrite tries with it were minimal. but it should be good enough that any AHK can customize/debug it for his reg2ahk conversion needs.
Code:
/*
Either select a reg-file a Windows explorer Window (folder view with address needed), and press Win+X to convert the selected (focused) file, or specify the "filepath" below and run script
*/
;filepath:= "C:\example.reg"
#NoEnv
#SingleInstance, Force
SendMode, Input
SetBatchLines, -1
;AutoTrim, Off
If filepath !=
Goto, RegConvert
GroupAdd, Explore, ahk_class CabinetWClass
GroupAdd, Explore, ahk_class ExploreWClass
Return
#IfWinActive ahk_group Explore
#x::
ControlGetText, dir, Edit1, A
ControlGet, file, List, Focused Col1, SysListView321, A
filepath:= StrLen(dir)=3 ? dir . file : dir . "\" . file
;StringTrimRight, filename, file, 4
;StringTrimRight, partpath, filepath, 4
RegConvert:
FileRead, regFile, %filepath%
If ( NumGet( regFile,0,"UShort" ) = 0xFEFF )
regFile:= UTOA( ®File+2 )
Loop,Parse,regFile,`n,`r
{
If (A_Index == 1)
{
If (A_LoopField != "Windows Registry Editor Version 5.00")
{
MsgBox,4,Label not detected: "Windows Registry Editor Version 5.00",This script is only designed to work with "Windows Registry Editor Version 5.00" reg-files.`nContinue anyway?,20
IfMsgBox No
ExitApp
}
}
;ASSUMPTION 1: only and all lines for registry keys begin with [
Else If (SubStr(A_LoopField,1,1) == "[")
{
bs:= InStr(A_LoopField, "\" ), root:= SubStr(A_LoopField,2,bs-2), sub:= SubStr(A_LoopField, bs+1)
StringTrimRight,sub,sub,1 ;to remove ]
vType:= "REG_EXPAND_SZ" ;is this type to add subkey?
regAHK.= "`n" . root . "," . sub
previous:=1 ;used to track sequence of extraction (1=root/sub, 2=value, 3=multi-line value)
Continue
}
Else If (A_LoopField != "")
{
;ASSUMPTION 2: only and all non-empty* lines for registry values and data begin with either @ or ". (*keys with only default value are considered empty)
;ASSUMPTION 3: value name and data are separated by the first equality sign preceded by @ or ", and succeeded by ", dword:, or hex*:, where the * stands for either no character or a hexadecimal value enclosed in brackets.
;In case of the hex values, the leading 0x common to them all(?) is no present. That is, value name-data delimiters consist of @=", @=dword:, @=hex, "=hex, and "=dword:, where the hex deliminters, if extended rightward, include values such as "=hex:, @=hex(0):, "=hex(b):, "=hex(747a756b): and so forth, but always end with :
;if multi-line value, grab it and append it to previous data
If (previous==3)
$pattern = U)^(\s+)(?P<Data>.*)(?P<Multi>\\?)$
Else $pattern = U)^["@](?P<Name>.*)(?:["@]?=(?P<Type>["]|dword:|hex.*:))(?P<Data>.*)(?P<Multi>["\\]?)$
RegExMatch( A_LoopField, $pattern, v)
;MSGBOX vName: %vName%`n`nvType: %vType%`n`nvData: %vData%`n`nvMulti: %vMulti%`n`n`n`nALF)%A_LoopField%
;define reg value type (needed for regWrite)
If (vMulti=="\")
{
If (previous==3)
{
regAHK.= vData
Continue
}
vType:= "REG_MULTI_SZ"
}
Else If (vType == """")
{
;ASSUMPTION 4 (still to check this...): double backslashes only occur REG_SZ values of describing file or program paths
StringReplace,vData,vData,\\,\,All
vType:= "REG_SZ"
}
Else
{
vType:= (vType=="dword:") ? "REG_DWORD" : "REG_BINARY"
/*
;statements below were included as examples or a base for
;manipulating dword and hex data (for example to compare to another format)
;presently, the dword condition would add spaces between paits binary data
If (vType == "REG_DWORD")
vData:= RegExReplace(vData, "..(?=.)", "$0 ")
;the condition below may be used to represent decimal data values as hexadecimals
Else If (vType == "REG_BINARY")
{
SetFormat, IntegerFast, H
vData:= % "0x" SubStr("00000000" SubStr(vData+0, 3), -7)
SetFormat, IntegerFast, D
}
*/
}
regAHK.= "`n" . vType . "," . root . "," . sub . "," . vName . "," . vData
previous:= (vMulti=="\") ? 3 : 2
}
;if blank line, zero tracking
Else previous=
}
MsgBox % regAHK
;FileAppend, regAHK, RegConversion.txt
regFile:="", regAHK:="", root:="", sub:="", vName:="", vData:="", vType:="", vMulti:=""
Return
UTOA( pUnicode )
{ ;Unicode to Ansi
VarSetCapacity( Ansi,(nSz:=DllCall( "lstrlenW", UInt,pUnicode )+1) )
DllCall( "WideCharToMultiByte", Int,0, Int,0, UInt,pUnicode, UInt,nSz, Str,Ansi, UInt,nSz, Int,0, Int,0 )
Return Ansi
}
;function below is not used by the script, but I left it in because it may be useful in related matters. It splits registry paths into root, subkey, value name and value data. it checks local registry for the inputed value or subkey, and in the former case, returns the local value if it exists but differs from the input string.
RegEntrySplit(RegString="")
{
global
RegExMatch(RegString,"i)^(HKLM|HKCR|HKCU|HKU|HKCC|HKEY_LOCAL_MACHINE|HKEY_USERS|HKEY_CURRENT_USER|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG)\\(?:((.*)\\(.*?)(?::\s)(.*)|.*))", rPath)
root:= rPath1
If rPath3 <>
{
sub:= rPath3
vname:= rPath4
val:= rPath5
If SubStr(val,1,1) = """" && SubStr(val, 0,1) = """"
StringMid,val,val,2,% StrLen(val)-2 ;remove excess "
RegRead, valNow, %root%, %sub%, %vname%
If valNow <>
Return root "`n" sub "`n" vname "`n" val "`n" valNow
Else Return 0
}
Else
{
sub:= rPath2, keycount:= 0
Loop %root%, %sub%, 1 ; checks if key exists
keycount++
If (keycount > 0)
Return root "`n" sub
Else Return 0
}
}