PDA

View Full Version : Read and Write Binary Registry Keys



Dr.K
07-31-2008, 01:20 PM
Help, MSDN is arguing with itself again.

This page claims that there is no way to read or modify binary keys, only strings and numbers. (these functions use Windows API calls)
http://support.microsoft.com/kb/145679

However, this article suggests that you can use the StdRegProv class of the WMI to open, enumerate, read and write Binary keys.
http://msdn.microsoft.com/en-us/library/aa392388(VS.85).aspx

Except... that I can't make it work. I found a bunch of code snipets that I pieced together, but it still errs out on me. I think maybe its a data-type issue with setting up the output array.

All I want to do is modify HKEY_CURRENT_USER, "Printers\Settings", "Adobe PDF"

I am familar with working with binary data in Byte Arrays, I just can't the data in or out of the registry key!

Please provide a working function, or point me to where I can find one.

Bob Phillips
07-31-2008, 02:26 PM
It is easy with Winndows Scripting



Dim oWSH As Object

Set oWSH = CreateObject("WScript.Shell")

oWSH.RegWrite "HKCU\Printers\Settings\Adobe PDF", 1, "REG_BINARY"

Kenneth Hobs
07-31-2008, 02:27 PM
What have you tried? Can you not read and write it as a string?

Here are some functions that might help.
' 32-bit declarations
Private Declare Function RegOpenKeyA Lib "ADVAPI32.DLL" _
(ByVal hKey As Long, ByVal sSubKey As String, _
ByRef hkeyResult As Long) As Long

Private Declare Function RegCloseKey Lib "ADVAPI32.DLL" _
(ByVal hKey As Long) As Long

Private Declare Function RegSetValueExA Lib "ADVAPI32.DLL" _
(ByVal hKey As Long, ByVal sValueName As String, _
ByVal dwReserved As Long, ByVal dwType As Long, _
ByVal sValue As String, ByVal dwSize As Long) As Long

Private Declare Function RegCreateKeyA Lib "ADVAPI32.DLL" _
(ByVal hKey As Long, ByVal sSubKey As String, _
ByRef hkeyResult As Long) As Long

Private Declare Function RegQueryValueExA Lib "ADVAPI32.DLL" _
(ByVal hKey As Long, ByVal sValueName As String, _
ByVal dwReserved As Long, ByRef lValueType As Long, _
ByVal sValue As String, ByRef lResultLen As Long) As Long

Private Function GetRegistry(Key, Path, ByVal ValueName As String)
' Reads a value from the Windows Registry

Dim hKey As Long
Dim lValueType As Long
Dim sResult As String
Dim lResultLen As Long
Dim ResultLen As Long
Dim x, TheKey As Long

TheKey = -99
Select Case UCase(Key)
Case "HKEY_CLASSES_ROOT": TheKey = &H80000000
Case "HKEY_CURRENT_USER": TheKey = &H80000001
Case "HKEY_LOCAL_MACHINE": TheKey = &H80000002
Case "HKEY_USERS": TheKey = &H80000003
Case "HKEY_CURRENT_CONFIG": TheKey = &H80000004
Case "HKEY_DYN_DATA": TheKey = &H80000005
End Select

' Exit if key is not found
If TheKey = -99 Then
GetRegistry = "Not Found"
Exit Function
End If

If RegOpenKeyA(TheKey, Path, hKey) <> 0 Then _
x = RegCreateKeyA(TheKey, Path, hKey)

sResult = Space(100)
lResultLen = 100

x = RegQueryValueExA(hKey, ValueName, 0, lValueType, _
sResult, lResultLen)

Select Case x
Case 0: GetRegistry = Left(sResult, lResultLen - 1)
Case Else: GetRegistry = "Not Found"
End Select

RegCloseKey hKey
End Function

Private Function WriteRegistry(ByVal Key As String, _
ByVal Path As String, ByVal entry As String, _
ByVal value As String)

Dim hKey As Long, TheKey As Long, x As Boolean
Dim lValueType As Long
Dim sResult As String
Dim lResultLen As Long

TheKey = -99
Select Case UCase(Key)
Case "HKEY_CLASSES_ROOT": TheKey = &H80000000
Case "HKEY_CURRENT_USER": TheKey = &H80000001
Case "HKEY_LOCAL_MACHINE": TheKey = &H80000002
Case "HKEY_USERS": TheKey = &H80000003
Case "HKEY_CURRENT_CONFIG": TheKey = &H80000004
Case "HKEY_DYN_DATA": TheKey = &H80000005
End Select

' Exit if key is not found
If TheKey = -99 Then
WriteRegistry = False
Exit Function
End If

' Make sure key exists
If RegOpenKeyA(TheKey, Path, hKey) <> 0 Then
x = RegCreateKeyA(TheKey, Path, hKey)
End If

x = RegSetValueExA(hKey, entry, 0, 1, value, Len(value) + 1)
If x = 0 Then WriteRegistry = True Else WriteRegistry = False
End Function

Dr.K
08-01-2008, 07:56 AM
What have you tried? Can you not read and write it as a string?


Well, I thought you needed to avoid that: reading in Binary data as Strings destroys some of the data, doesn't it? This is why I've always been careful to use Arrays of Bytes, to avoid tranlsating any of the data.

Anyway, I was able to get the WSH working, but I still couldn't get the data type to work... I had to use a Variant, which seems lazy to me.

Sub DumpAdobeKey()

Dim x As Integer
Dim varBin As Variant
Dim oWSH As Object


Set oWSH = CreateObject("WScript.Shell")
varBin = oWSH.regread("HKCU\Printers\Settings\Adobe PDF")

ActiveSheet.Columns(1).Insert xlShiftToRight

For x = 0 To 387
Cells(x + 1, 1).Value = varBin(x)
Next x

End Sub

The RegRead Method outputs an Array of Integers, not Bytes, but I stil couldn't set up an Integer Array in such a way that it worked, therefore the Variant.

Thanks for the help.