Thanks to you, tomte and fincs. You are doing a wonderful job in maintaining AutoHotkey alive and helping the newbies like me!
BTW, tomte, any chance to have a function to parse the x64 registry? ;-)
RegRead64() and RegWrite64() - no redirect to Wow6432Node
Started by
tomte
, Jan 06 2009 02:13 PM
31 replies to this topic
I've recently released (2 days ago) a native 64-bit build of AutoHotkey_L and registry loops might even work, the catch is that DllCall and RegisterCallback are not implemented at the moment.
#17
-
Posted 20 May 2010 - 04:10 PM
I've noticed that. Great job! But I need to parse the registry for x64 AND x86 apps, so even if, with your AHK_L64, I can remove the two x64 function needed by the 32bit versions of AutoHotkey, I will need equivalent functions to read the registry in 32bit mode. So, currently, there is no solution, until your new version will support DLLcall.
But I've found the M$ doc of RegEnumKey(), and I'll try to implement it. With the numerous examples of DLLcalls in this forum and what's I've learned today, that should be possible.
Thanks again!
But I've found the M$ doc of RegEnumKey(), and I'll try to implement it. With the numerous examples of DLLcalls in this forum and what's I've learned today, that should be possible.
Thanks again!
#18
-
Posted 20 May 2010 - 04:20 PM
r0lZ
I've somewhat expanded the RegRead64() function to (partially) implement the REG_QWORD registry data type.
You have to add this line at the end of the data types list:
and this, in the cases list later in the original code:
This code is for AHK_L. If you use the mainstream AHK, replace RegQueryValueEx by RegQueryValueExA.
That works well, but due to a AHK limitation (at least in non-64bit versions), the unsigned 64bit integers have to be treated as signed, so you have to take care if the returned value is negative.
You have to add this line at the end of the data types list:
REG_QWORD := 11
and this, in the cases list later in the original code:
} Else If (sValueType == REG_QWORD) { VarSetCapacity(sValue, vValueSize:=8) DllCall("Advapi32.dll\RegQueryValueEx", "uint", hKey, "str", sValueName, "uint", 0, "uint", 0, "uint64*", sValue, "uint*", vValueSize)Note the "uint64*" instead of the usual "uint*".
This code is for AHK_L. If you use the mainstream AHK, replace RegQueryValueEx by RegQueryValueExA.
That works well, but due to a AHK limitation (at least in non-64bit versions), the unsigned 64bit integers have to be treated as signed, so you have to take care if the returned value is negative.
#19
-
Posted 20 May 2010 - 04:49 PM
r0lZ
I've been meaning to post my RegEnumKey64(), It works for me but not a full replacement for the Reg loop.But I've found the M$ doc of RegEnumKey(), and I'll try to implement it. With the numerous examples of DLLcalls in this forum and what's I've learned today, that should be possible.
Example code:
Loop { If Not GDFGamePath := RegEnumKey64("HKEY_LOCAL_MACHINE", "SOFTWARE\Microsoft\Windows\CurrentVersion\GameUX" . RegPath, (A_Index - 1)) Break GDFGamePath%GameNr% := RegRead64("HKEY_LOCAL_MACHINE", "SOFTWARE\Microsoft\Windows\CurrentVersion\GameUX" . RegPath . "" . GDFGamePath, GamePath) }Hopefully this is useful, I'll add more info if needed, don't have time right now.
RegEnumKey64(sRootKey, sKeyName, sValueName = "", DataMaxSize=1024) { HKEY_CLASSES_ROOT := 0x80000000 ; http://msdn.microsoft.com/en-us/library/aa393286.aspx HKEY_CURRENT_USER := 0x80000001 HKEY_LOCAL_MACHINE := 0x80000002 HKEY_USERS := 0x80000003 HKEY_CURRENT_CONFIG := 0x80000005 HKEY_DYN_DATA := 0x80000006 HKCR := HKEY_CLASSES_ROOT HKCU := HKEY_CURRENT_USER HKLM := HKEY_LOCAL_MACHINE HKU := HKEY_USERS HKCC := HKEY_CURRENT_CONFIG REG_NONE := 0 ; http://msdn.microsoft.com/en-us/library/ms724884.aspx REG_SZ := 1 REG_EXPAND_SZ := 2 REG_BINARY := 3 REG_DWORD := 4 REG_DWORD_BIG_ENDIAN := 5 REG_LINK := 6 REG_MULTI_SZ := 7 REG_RESOURCE_LIST := 8 KEY_QUERY_VALUE := 0x0001 ; http://msdn.microsoft.com/en-us/library/ms724878.aspx KEY_WOW64_64KEY := 0x0100 ; http://msdn.microsoft.com/en-gb/library/aa384129.aspx (do not redirect to Wow6432Node on 64-bit machines) KEY_SET_VALUE := 0x0002 KEY_WRITE := 0x20006 KEY_ENUMERATE_SUB_KEYS := 0x0008 ERROR_MORE_DATA := 234 ERROR_NO_MORE_ITEMS := 259 ERROR_SUCCESS := 0 myhKey := %sRootKey% ; pick out value (0x8000000x) from list of HKEY_xx vars IfEqual,myhKey,, { ; Error - Invalid root key ErrorLevel := 3 return "" } RegAccessRight := KEY_QUERY_VALUE + KEY_WOW64_64KEY + KEY_ENUMERATE_SUB_KEYS DllCall("Advapi32.dll\RegOpenKeyExA", "uint", myhKey, "str", sKeyName, "uint", 0, "uint", RegAccessRight, "uint*", hKey) ; open key VarSetCapacity(sValue, vValueSize := 64000) If DllCall("Advapi32.dll\RegEnumKeyExA", "uint", hKey, "uint", sValueName, "str", sValue, "uint*", vValueSize, "uint", 0, "uint", 0, "uint", 0, "uint", 0) ; get value type sValue := "" DllCall("Advapi32.dll\RegCloseKey", "uint", hKey) return sValue }
jonib
#20
-
Posted 21 May 2010 - 01:17 AM
I've written something very similar, but I use the AHK_L Object() to return more information in an array. Also, I've written another function to return the value names (and again more info in an array), using RegEnumValue().
With these two functions, it is easy to parse a whole branch of the registry, although it's not so easy than with the native AHK loop method.
Maybe I'll post my code here later, but it is not finished yet.
Thanks anyway for your help!
With these two functions, it is easy to parse a whole branch of the registry, although it's not so easy than with the native AHK loop method.
Maybe I'll post my code here later, but it is not finished yet.
Thanks anyway for your help!
#21
-
Posted 21 May 2010 - 10:57 AM
r0lZ
I am trying to write registry entries on a remote 64bit computer.
We are using this to add notices to users via the regkeys below.
Any ideas?
HKEY_LOCAL_MACHINE, Software\Microsoft\Windows NT\CurrentVersion\Winlogon, LegalNoticeCaption
and
HKEY_LOCAL_MACHINE, Software\Microsoft\Windows NT\CurrentVersion\Winlogon, LegalNoticeText
We are using this to add notices to users via the regkeys below.
Any ideas?
HKEY_LOCAL_MACHINE, Software\Microsoft\Windows NT\CurrentVersion\Winlogon, LegalNoticeCaption
and
HKEY_LOCAL_MACHINE, Software\Microsoft\Windows NT\CurrentVersion\Winlogon, LegalNoticeText
#22
-
Posted 17 June 2010 - 09:57 PM
How about deleting a key?
Shouldn't it look like this?DllCall("Advapi32.dll\RegOpenKeyExA", "uint", myhKey, "str", sKeyName, "uint", 0, "uint", RegAccessRight, "uint*", hKey) DllCall("Advapi32.dll\RegDeleteKeyExA", "uint", hKey, "str", sKeyName, "uint", RegAccessRight , "uint", 0)
UP
#23
-
Posted 20 June 2011 - 09:08 AM
Hi, y'all! I have a problem here.
I want to write this key (onto 64bit windows 7)(I have AutoHotkey_L), but it writes to the WOW key anyway.
regwrite, REG_SZ, HKEY_LOCAL_MACHINE, SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\Namespace\{21EC2020-3AEA-1069-A2DD-08002B30309D} ;Add Control Panel to My Computer (no keys)
So I tried regwrite64, but it didn't write to the right key either.
regwrite64("REG_SZ", "HKEY_LOCAL_MACHINE", "SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\Namespace\{21EC2020-3AEA-1069-A2DD-08002B30309D}")
Am I missing something?
I want to write this key (onto 64bit windows 7)(I have AutoHotkey_L), but it writes to the WOW key anyway.
regwrite, REG_SZ, HKEY_LOCAL_MACHINE, SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\Namespace\{21EC2020-3AEA-1069-A2DD-08002B30309D} ;Add Control Panel to My Computer (no keys)
So I tried regwrite64, but it didn't write to the right key either.
regwrite64("REG_SZ", "HKEY_LOCAL_MACHINE", "SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\Namespace\{21EC2020-3AEA-1069-A2DD-08002B30309D}")
Am I missing something?
#24
-
Posted 26 July 2011 - 08:31 PM
I think you must use regwrite64 and AHK_L X64 and have administrator rights to write to the right key!
#25
-
Posted 26 July 2011 - 08:52 PM
r0lZ
AHK_L X64? I didn't know there was a 64bit version. That might help...
#26
-
Posted 26 July 2011 - 08:57 PM
I am using a 32bit system, but am provisioning a 64bit system, and don't want to install 64bit AHK. Is there a location where I can download just the 64bit AutoHotkey binary without any installer?
#27
-
Posted 26 July 2011 - 09:00 PM
I don't know, but installers are mainly ZIP archives with an executable program. You should be able to extract the binaries with a good archiver program such as 7-zip, without installing the package.
There are 3 versions of AHK_L: ANSI 32 bit, unicode 32 bit and unicode 64 bit.
Personally, I install the 3 AHK_L versions in the same folder, but I rename the binaries before installing the next version, to keep them all. Only Autohotkey.exe and AutoHotkeySC.bin are different in the different packages.
Of course, you cannot run the 64 bit version on a 32 bit computer, but you can compile a 64 bit version of your script, and test it on another computer.
There are 3 versions of AHK_L: ANSI 32 bit, unicode 32 bit and unicode 64 bit.
Personally, I install the 3 AHK_L versions in the same folder, but I rename the binaries before installing the next version, to keep them all. Only Autohotkey.exe and AutoHotkeySC.bin are different in the different packages.
Of course, you cannot run the 64 bit version on a 32 bit computer, but you can compile a 64 bit version of your script, and test it on another computer.
#28
-
Posted 26 July 2011 - 09:17 PM
r0lZ
Yes, I know I can't run the 64bit version on my 32bit computer, but I can copy the 64bit one to the b4bit computer and use it there until I am finished with it.
It never occurred to me to unzip the installer! Now, I see 3 AutoHotkey.exe 's in there! I assume the 64bit version is the larger-sized one without any icon.
After I did that, hey, it works! Now, if only that reg64 script would work for binary values!
Thanks for your advice.
It never occurred to me to unzip the installer! Now, I see 3 AutoHotkey.exe 's in there! I assume the 64bit version is the larger-sized one without any icon.
After I did that, hey, it works! Now, if only that reg64 script would work for binary values!
Thanks for your advice.
#29
-
Posted 26 July 2011 - 09:37 PM
I dont know what im doing wrong. I copied the code exactly and even when I try a registry that is in both 64 and 32 bit sections I still get an error. Here is the code:
; _reg64.ahk ver 0.1 by tomte ; Script for AutoHotkey ( http://www.autohotkey.com/ ) ; ; Provides RegRead64() and RegWrite64() functions that do not redirect to Wow6432Node on 64-bit machines ; RegRead64() and RegWrite64() takes the same parameters as regular AHK RegRead and RegWrite commands, plus one optional DataMaxSize param for RegRead64() ; ; RegRead64() can handle the same types of values as AHK RegRead: ; REG_SZ, REG_EXPAND_SZ, REG_MULTI_SZ, REG_DWORD, and REG_BINARY ; (values are returned in same fashion as with RegRead - REG_BINARY as hex string, REG_MULTI_SZ split with linefeed etc.) ; ; RegWrite64() can handle REG_SZ, REG_EXPAND_SZ and REG_DWORD only ; ; Usage: ; myvalue := RegRead64("HKEY_LOCAL_MACHINE", "SOFTWARE\SomeCompany\Product\Subkey", "valuename") ; RegWrite64("REG_SZ", "HKEY_LOCAL_MACHINE", "SOFTWARE\SomeCompany\Product\Subkey", "valuename", "mystring") ; If the value name is blank/omitted the subkey's default value is used, if the value is omitted with RegWrite64() a blank/zero value is written ; RegRead64(sRootKey, sKeyName, sValueName = "", DataMaxSize=1024) { HKEY_CLASSES_ROOT := 0x80000000 ; http://msdn.microsoft.com/en-us/library/aa393286.aspx HKEY_CURRENT_USER := 0x80000001 HKEY_LOCAL_MACHINE := 0x80000002 HKEY_USERS := 0x80000003 HKEY_CURRENT_CONFIG := 0x80000005 HKEY_DYN_DATA := 0x80000006 HKCR := HKEY_CLASSES_ROOT HKCU := HKEY_CURRENT_USER HKLM := HKEY_LOCAL_MACHINE HKU := HKEY_USERS HKCC := HKEY_CURRENT_CONFIG REG_NONE := 0 ; http://msdn.microsoft.com/en-us/library/ms724884.aspx REG_SZ := 1 REG_EXPAND_SZ := 2 REG_BINARY := 3 REG_DWORD := 4 REG_DWORD_BIG_ENDIAN := 5 REG_LINK := 6 REG_MULTI_SZ := 7 REG_RESOURCE_LIST := 8 KEY_QUERY_VALUE := 0x0001 ; http://msdn.microsoft.com/en-us/library/ms724878.aspx KEY_WOW64_64KEY := 0x0100 ; http://msdn.microsoft.com/en-gb/library/aa384129.aspx (do not redirect to Wow6432Node on 64-bit machines) KEY_SET_VALUE := 0x0002 KEY_WRITE := 0x20006 myhKey := %sRootKey% ; pick out value (0x8000000x) from list of HKEY_xx vars IfEqual,myhKey,, { ; Error - Invalid root key ErrorLevel := 3 return "" } RegAccessRight := KEY_QUERY_VALUE + KEY_WOW64_64KEY DllCall("Advapi32.dll\RegOpenKeyExA", "uint", myhKey, "str", sKeyName, "uint", 0, "uint", RegAccessRight, "uint*", hKey) ; open key DllCall("Advapi32.dll\RegQueryValueExA", "uint", hKey, "str", sValueName, "uint", 0, "uint*", sValueType, "uint", 0, "uint", 0) ; get value type If (sValueType == REG_SZ or sValueType == REG_EXPAND_SZ) { VarSetCapacity(sValue, vValueSize:=DataMaxSize) DllCall("Advapi32.dll\RegQueryValueExA", "uint", hKey, "str", sValueName, "uint", 0, "uint", 0, "str", sValue, "uint*", vValueSize) ; get string or string-exp } Else If (sValueType == REG_DWORD) { VarSetCapacity(sValue, vValueSize:=4) DllCall("Advapi32.dll\RegQueryValueExA", "uint", hKey, "str", sValueName, "uint", 0, "uint", 0, "uint*", sValue, "uint*", vValueSize) ; get dword } Else If (sValueType == REG_MULTI_SZ) { VarSetCapacity(sTmp, vValueSize:=DataMaxSize) DllCall("Advapi32.dll\RegQueryValueExA", "uint", hKey, "str", sValueName, "uint", 0, "uint", 0, "str", sTmp, "uint*", vValueSize) ; get string-mult sValue := ExtractData(&sTmp) "`n" Loop { If (errorLevel+2 >= &sTmp + vValueSize) Break sValue := sValue ExtractData( errorLevel+1 ) "`n" } } Else If (sValueType == REG_BINARY) { VarSetCapacity(sTmp, vValueSize:=DataMaxSize) DllCall("Advapi32.dll\RegQueryValueExA", "uint", hKey, "str", sValueName, "uint", 0, "uint", 0, "str", sTmp, "uint*", vValueSize) ; get binary sValue := "" SetFormat, integer, h Loop %vValueSize% { hex := SubStr(Asc(SubStr(sTmp,A_Index,1)),3) StringUpper, hex, hex sValue := sValue hex } SetFormat, integer, d } Else { ; value does not exist or unsupported value type DllCall("Advapi32.dll\RegCloseKey", "uint", hKey) ErrorLevel := 1 return "" } DllCall("Advapi32.dll\RegCloseKey", "uint", hKey) return sValue } RegWrite64(sValueType, sRootKey, sKeyName, sValueName = "", sValue = "") { HKEY_CLASSES_ROOT := 0x80000000 ; http://msdn.microsoft.com/en-us/library/aa393286.aspx HKEY_CURRENT_USER := 0x80000001 HKEY_LOCAL_MACHINE := 0x80000002 HKEY_USERS := 0x80000003 HKEY_CURRENT_CONFIG := 0x80000005 HKEY_DYN_DATA := 0x80000006 HKCR := HKEY_CLASSES_ROOT HKCU := HKEY_CURRENT_USER HKLM := HKEY_LOCAL_MACHINE HKU := HKEY_USERS HKCC := HKEY_CURRENT_CONFIG REG_NONE := 0 ; http://msdn.microsoft.com/en-us/library/ms724884.aspx REG_SZ := 1 REG_EXPAND_SZ := 2 REG_BINARY := 3 REG_DWORD := 4 REG_DWORD_BIG_ENDIAN := 5 REG_LINK := 6 REG_MULTI_SZ := 7 REG_RESOURCE_LIST := 8 KEY_QUERY_VALUE := 0x0001 ; http://msdn.microsoft.com/en-us/library/ms724878.aspx KEY_WOW64_64KEY := 0x0100 ; http://msdn.microsoft.com/en-gb/library/aa384129.aspx (do not redirect to Wow6432Node on 64-bit machines) KEY_SET_VALUE := 0x0002 KEY_WRITE := 0x20006 myhKey := %sRootKey% ; pick out value (0x8000000x) from list of HKEY_xx vars myValueType := %sValueType% ; pick out value (0-8) from list of REG_SZ,REG_DWORD etc. types IfEqual,myhKey,, { ; Error - Invalid root key ErrorLevel := 3 return ErrorLevel } IfEqual,myValueType,, { ; Error - Invalid value type ErrorLevel := 2 return ErrorLevel } RegAccessRight := KEY_QUERY_VALUE + KEY_WOW64_64KEY + KEY_WRITE DllCall("Advapi32.dll\RegCreateKeyExA", "uint", myhKey, "str", sKeyName, "uint", 0, "uint", 0, "uint", 0, "uint", RegAccessRight, "uint", 0, "uint*", hKey) ; open/create key If (myValueType == REG_SZ or myValueType == REG_EXPAND_SZ) { vValueSize := StrLen(sValue) + 1 DllCall("Advapi32.dll\RegSetValueExA", "uint", hKey, "str", sValueName, "uint", 0, "uint", myValueType, "str", sValue, "uint", vValueSize) ; write string } Else If (myValueType == REG_DWORD) { vValueSize := 4 DllCall("Advapi32.dll\RegSetValueExA", "uint", hKey, "str", sValueName, "uint", 0, "uint", myValueType, "uint*", sValue, "uint", vValueSize) ; write dword } Else { ; REG_MULTI_SZ, REG_BINARY, or other unsupported value type ErrorLevel := 2 } DllCall("Advapi32.dll\RegCloseKey", "uint", hKey) return ErrorLevel } ExtractData(pointer) { ; http://www.autohotkey.com/forum/viewtopic.php?p=91578#91578 SKAN Loop { errorLevel := ( pointer+(A_Index-1) ) Asc := *( errorLevel ) IfEqual, Asc, 0, Break ; Break if NULL Character String := String . Chr(Asc) } Return String } ; Thanks Chris, Lexikos and SKAN ; http://www.autohotkey.com/forum/topic37710-15.html ; http://www.autohotkey.com/forum/viewtopic.php?p=235522 5:: out := RegRead64("HKEY_LOCAL_MACHINE", "SOFTWARE\Microsoft\Windows\CurrentVersion\Audio", "EnableCaptureMonitor") MsgBox %out% err:%ErrorLevel% return 4:: send ^s Reload return
Can someone help me
#30
-
Posted 11 April 2014 - 11:11 PM