none
Cara Menggunakan Fungsi RegEnumValue Di VB.NET

    Question

  • Halo semua, ada yang tahu gak cara menggunakan

    <DllImport("advapi32.dll", SetLastError:=True)> _
        Private Shared Function RegEnumValue(ByVal hKey As IntPtr, ByVal dwIndex As Integer, ByVal lpValueName As StringBuilder, ByRef lpcValueName As Integer, _
                                             ByVal lpReserved As IntPtr, ByRef lpType As Integer, ByRef lpData As StringBuilder, ByRef lpcbData As Integer) As Integer
      End Function

    untuk lpType, lpData, lpcbData cara dapatin nilainya bagaimana ya?

    Salam

    Xan To

    Monday, January 13, 2014 11:48 AM

Answers

  • Hallo Andy terima kasih atas supportnya, baik saya akan pos codenya....

    untuk VB6 berikut kode programnya

    ' This code is licensed according to the terms and conditions listed here.
    ' Declarations and such needed for the example:
    ' (Copy them to the (declarations) section of a module.)
    Private Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal hkey _
        As Long, ByVal dwIndex As Long, ByVal lpValueName As String, lpcbValueName As Long, _
        ByVal lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long
    Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hkey _
        As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired _
        As Long, phkResult As Long) As Long
    Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hkey As Long) As Long
    Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (Destination As Any, _
        Source As Any, ByVal Length As Long)
    Const HKEY_LOCAL_MACHINE = &H80000002
    Const KEY_QUERY_VALUE = &H1
    Const REG_SZ = 1
    Const REG_BINARY = 3
    Const REG_DWORD = 4
    Const REG_MULTI_SZ = 7
    Const REG_EXPAND_SZ = 2
    Const REG_QWORD = 11
    Const HKEY_CURRENT_USER = &H80000001
    
    ' *** Place the following code inside a form window. ***
    Private Sub cmdRun_Click()
        Dim valuename As String     ' name of the value being retrieved
        Dim valuelen As Long        ' length of valuename
        Dim datatype As Long        ' receives data type of value
        Dim data(0 To 254) As Byte  ' 255-byte data buffer for read information
        Dim datalen As Long         ' size of data buffer information
        Dim datastring As String    ' will receive data converted to a string, if necessary
        Dim hkey As Long            ' handle to the registry key to enumerate the values of
        Dim index As Long           ' counter for the index of the value to enumerate
        Dim c As Long               ' counter variable
        Dim retval As Long          ' functions' return value
        
        ' Open the registry key to enumerate the values of.
        retval = RegOpenKeyEx(HKEY_CURRENT_USER, "Test\Test 2", _
            0, KEY_QUERY_VALUE, hkey)
        ' Check to see if an error occured.
        If retval <> 0 Then
            Debug.Print "Registry key could not be opened -- aborting."
            End  ' abort the program
        End If
        
        ' Begin enumerating the values.  Get each one, displaying its name.  If it's a null-
        ' terminated string or binary data, display it.  If not, say so.
        index = 0  ' initialize the counter
        While retval = 0  ' loop while successful
            ' Initialize the value name buffer.
            valuename = Space(255)  ' 255-space buffer
            valuelen = 255  ' length of the string
            datalen = 255  ' size of data buffer
            ' Get the next value to be enumerated
            retval = RegEnumValue(hkey, index, valuename, valuelen, 0, datatype, data(0), datalen)
            If retval = 0 Then  ' if successful, display information
                ' Extract the useful information from the value name buffer and display it.
                valuename = Left(valuename, valuelen)
                Debug.Print "Value Name: "; valuename
                ' Determine the data type of the value and display it.
                Select Case datatype
                Case REG_SZ  ' null-terminated string
                    ' Copy the information from the byte array into the string.
                    ' We subtract one because we don't want the trailing null.
                    datastring = Space(datalen - 1)  ' make just enough room in the string
                    CopyMemory ByVal datastring, data(0), datalen - 1  ' copy useful data
                    Debug.Print "  Data (string): "; datastring
                Case REG_BINARY  ' binary data
                    ' Display the hexadecimal values of each byte of data, separated by
                    ' sapces.  Use the datastring buffer to allow us to assure each byte
                    ' is represented by a two-character string.
                    Debug.Print "  Data (binary):";
                    For c = 0 To datalen - 1  ' loop through returned information
                        datastring = Hex(data(c))  ' convert value into hex
                        ' If needed, add leading zero(s).
                        If Len(datastring) < 2 Then datastring = _
                            String(2 - Len(datastring), "0") & datastring
                        Debug.Print " "; datastring;
                    Next c
                    Debug.Print  ' end the line
                Case REG_DWORD
                    Dim Longvalue As Long
                    Debug.Print "  Data (DWORD):";
                    CopyMemory Longvalue, data(0), datalen - 1
                    Debug.Print ""; Longvalue;
                    Debug.Print  ' end the line
                Case REG_MULTI_SZ
                    datastring = Space(datalen - 1)  ' make just enough room in the string
                    CopyMemory ByVal datastring, data(0), datalen - 1  ' copy useful data
                    Debug.Print "  Data (MULTI_SZ): "; Replace(datastring, Chr$(0), " ")
                Case REG_EXPAND_SZ
                    datastring = Space(datalen - 1)  ' make just enough room in the string
                    CopyMemory ByVal datastring, data(0), datalen - 1  ' copy useful data
                    Debug.Print "  Data (EXPAND_SZ): "; datastring
                Case REG_QWORD
                    Debug.Print "  Data (QWORD):";
                    For c = 0 To datalen - 1  ' loop through returned information
                        datastring = Hex(data(c))  ' convert value into hex
                        ' If needed, add leading zero(s).
                        If Len(datastring) < 2 Then datastring = _
                            String(2 - Len(datastring), "0") & datastring
                        Debug.Print " "; datastring;
                    Next c
                    Debug.Print  ' end the line
                Case Else  ' a data type this example doesn't handle
                    Debug.Print "This example doesn't know how to read that kind of data."
                End Select
            End If
            index = index + 1  ' increment the index counter
        Wend  ' end the loop
        
        ' Close the registry key.
        retval = RegCloseKey(hkey)
    End Sub
    
    Private Function TrimNull(startstr As String) As String
    On Error Resume Next
        iPos = InStr(startstr, Chr$(0))
        If iPos Then
           TrimNull = Left$(startstr, iPos - 1)
           Exit Function
        End If
        TrimNull = startstr
    End Function

    Hal yang perlu diperhatikan adalah untuk nilai kembalian dari lpData berupa Array, variabel yang digunakan adalah Any, saya gak tahu kenapa harus menggunakan Any, sy sudah coba menggunakan Byte atau Byte() tapi malah error.

    katakanlah sebuah Registry Isinya adalah
    Nama Value: New Value #1
    Type Value: REG_SZ
    Data Value: "kyyyyyy"

    Maka yang sebenarnya dikembalikan oleh lpData adalah Nilai ANSI dari k dan y:
    lpData(0)=107
    lpData(1)=121
    lpData(2)=121
    lpData(3)=121
    lpData(4)=121
    lpData(5)=121
    lpData(6)=121

    CopyMemory itu gunanya untuk mengubah Array ANSI menjadi String sehingga hasilnya "kyyyyyy"

    Sayangnya di VB.Net Variabel Any sudah tidak ada, beberapa orang menyarankan menggunakan StringBuilder sayangnya Stringbuilder tidak bisa memanipulasi data pada tipe registry REG_DWORD dan REG_MULTI_SZ sesuai dengan seharusnya, oleh karena itu kita harus menset-nya menjadi variabel Byte() jadi nilai yang dikembalikan oleh lpData pada RegEnumValue berupa Array Byte, hasilnya baru dimanipulasi secara manual sesuai dengan kebutuhan, berikut kode dalam VB.Net, semoga bermanfaat:

    <DllImport("advapi32.dll", SetLastError:=True)> _ Private Shared Function RegEnumValue(ByVal hKey As IntPtr, ByVal dwIndex As Integer, ByVal lpValueName As StringBuilder, ByRef lpcValueName As Integer, _ ByVal lpReserved As IntPtr, ByRef lpType As IntPtr, ByVal lpData As Byte(), ByRef lpcbData As IntPtr) As Integer End Function Private Const MAX_REG_KEYNAME_SIZE = 255 Private Const MAX_VALUE_NAME = 16383 Dim lpValueName As New StringBuilder(MAX_VALUE_NAME - 1) Dim lpcValueName As UInteger Dim sc As New StringCollection Dim CountRegKey, CountRegValue As UInteger Private Sub GetSubKeyNames(ByVal SubKey As String) Dim iKey, dwIndex, Result As Integer Dim SubhKey As IntPtr Dim lpname As New StringBuilder(MAX_VALUE_NAME - 1) Dim sSubkey As String Dim lpType As Integer Dim lpcbData As Integer Dim lpData(255) As Byte Dim value, Test, tmpValueName As String Try Result = RegOpenKeyEx(RegistryHive.CurrentUser, SubKey, 0, RegSam.KEY_ENUMERATE_SUB_KEYS Or RegSam.KEY_QUERY_VALUE, SubhKey) If Result <> 0 Then Throw New ApplicationException("Cannot access a closed registry key") End If lpcValueName = MAX_VALUE_NAME lpcbData = MAX_VALUE_NAME Do Result = RegEnumValue(SubhKey, dwIndex, lpValueName, lpcValueName, Nothing, lpType, lpData, lpcbData) If lpValueName.ToString = String.Empty Then tmpValueName = "@" Else tmpValueName = Chr(34) & lpValueName.ToString & Chr(34) ReDim Preserve lpData(lpcbData - 1) If Result = 259 Then Exit Do Select Case lpType Case RegType.REG_DWORD value = "" For index = 0 To lpcbData - 1 Test = Convert.ToString(lpData(index), 2) Test = New String("0", 8 - Test.Length) + Test value = Test + value Next Dim CResult = Convert.ToUInt32(value, 2) sc.Add(tmpValueName & "= " & lpType & " " & CResult.ToString) Case Else value = System.Text.ASCIIEncoding.ASCII.GetString(lpData) Test = value.Replace(ChrW(0), " ").Trim() sc.Add(tmpValueName & "= " & lpType & " " & Test.ToString) End Select dwIndex += 1 lpcValueName = MAX_VALUE_NAME lpcbData = MAX_VALUE_NAME ReDim lpData(lpcbData) CountRegValue += 1 Loop Do Result = RegEnumKeyEx(SubhKey, iKey, lpname, MAX_REG_KEYNAME_SIZE + 1, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero) If Result = 259 Then Exit Do If SubKey <> String.Empty Then sSubkey = SubKey & "\" & lpname.ToString Else sSubkey = lpname.ToString End If sc.Add("[" & sSubkey & "]") CountRegKey += 1 GetSubKeyNames(sSubkey) sSubkey = Replace(sSubkey, lpname.ToString, "") iKey += 1 Loop RegCloseKey(SubhKey) Catch ex As Exception End Try End Sub


    • Edited by Xan To Friday, January 24, 2014 7:42 AM
    • Marked as answer by Xan To Friday, January 24, 2014 8:06 AM
    Friday, January 24, 2014 7:40 AM

All replies

  • Hi

    Ada thread serupa yang menyarankan menggunakan ByVal StringBuilder

    Public Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal hKey As IntPtr,  ByVal dwIndex As  Integer, ByVal lpValueName  As StringBuilder,  ByRef lpcbValueName As  Integer, ByVal lpReserved  As Integer, ByRef lpType As Integer, ByVal lpData As  StringBuilder, ByRef lpcbData  As Integer) As Integer

    http://social.msdn.microsoft.com/Forums/en-US/3ae5e246-24b5-4a84-894b-881254a70605/regenumvalue-api-in-net?forum=vbinterop

    • Edited by britishdhez Wednesday, January 15, 2014 6:51 AM
    Wednesday, January 15, 2014 6:49 AM
  • Saya sudah menggunakan type Stringbuilder, tapi masalahnya untuk Type Registry REG_DWORD, gak mengembalikan nilai, padahal yang lain mengembalikan nilai.

    Silahkan di test codenya, saya menggunakan Windows XP.

    Imports Microsoft.Win32
    Imports System.Runtime.InteropServices
    Imports System.Text
    Imports System.Collections.Specialized
    
    Public Class frmGetSubKeyName
      <DllImport("advapi32.dll", SetLastError:=True)> _
        Private Shared Function RegEnumValue(ByVal hKey As IntPtr, ByVal dwIndex As Integer, ByVal lpValueName As StringBuilder, ByRef lpcValueName As Integer, _
                                             ByVal lpReserved As IntPtr, ByRef lpType As IntPtr, ByVal lpData As StringBuilder, ByRef lpcbData As IntPtr) As Integer
      End Function
    
      <DllImport("advapi32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)> _
      Private Shared Function RegOpenKeyEx(ByVal hKey As IntPtr, ByVal subKey As String, ByVal options As UInteger, _
                                           ByVal samDesired As RegSam, ByRef phkResult As IntPtr) As Integer
      End Function
    
      <DllImport("advapi32.dll", SetLastError:=True)> _
      Private Shared Function RegEnumKeyEx(ByVal hKey As IntPtr, ByVal dwIndex As Integer, ByVal lpName As StringBuilder, ByRef lpcName As Integer, _
                                           ByVal lpReserved As IntPtr, ByVal lpClass As IntPtr, ByVal lpcClass As IntPtr, ByVal lpftLastWriteTime As IntPtr) As Integer
      End Function
    
      <DllImport("advapi32.dll", SetLastError:=True)> _
      Private Shared Function RegCloseKey(ByVal hKey As IntPtr) As Integer
      End Function
    
      Private Enum RegSam
        KEY_QUERY_VALUE = 1 'Required to query the values of a registry key.
        KEY_SET_VALUE = 2 'Required to create, delete, or set a registry value.
        KEY_CREATE_SUB_KEY = 4 'Required to create a subkey of a registry key.
        KEY_ENUMERATE_SUB_KEYS = 8 'Required to enumerate the subkeys of a registry key.
        KEY_NOTIFY = &H10 'Required to request change notifications for a registry key or for subkeys of a registry key.
        KEY_CREATE_LINK = &H20 'Reserved for system use.
        KEY_WOW64_64KEY = &H100 'Indicates that an application on 64-bit Windows should operate on the 64-bit registry view. This flag is ignored by 32-bit Windows. For more information, see Accessing an Alternate Registry View. This flag must be combined using the OR operator with the other flags in this table that either query or access registry values. Windows 2000:  This flag is not supported.
        KEY_WOW64_32KEY = &H200 'Indicates that an application on 64-bit Windows should operate on the 32-bit registry view. This flag is ignored by 32-bit Windows. For more information, see Accessing an Alternate Registry View. This flag must be combined using the OR operator with the other flags in this table that either query or access registry values. Windows 2000:  This flag is not supported.
        KEY_ALL_ACCESS = &HF003F 'Combines the STANDARD_RIGHTS_REQUIRED, KEY_QUERY_VALUE, KEY_SET_VALUE, KEY_CREATE_SUB_KEY, KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY, and KEY_CREATE_LINK access rights.
        KEY_WRITE = &H20006 'Combines the STANDARD_RIGHTS_WRITE, KEY_SET_VALUE, and KEY_CREATE_SUB_KEY access rights.
        KEY_EXECUTE = &H20019 'Equivalent to KEY_READ.
        KEY_READ = &H20019 'Combines the STANDARD_RIGHTS_READ, KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY values.
      End Enum
    
      Private Enum RegHive
        HKEY_CLASSES_ROOT = &H80000000
        HKEY_CURRENT_USER = &H80000001
        HKEY_LOCAL_MACHINE = &H80000002
        HKEY_USERS = &H80000003
        HKEY_PERFORMANCE_DATA = &H80000004
        HKEY_PERFORMANCE_TEXT = &H80000050
        HKEY_PERFORMANCE_NLSTEXT = &H80000060
        HKEY_CURRENT_CONFIG = &H80000005
        HKEY_DYN_DATA = &H80000006
        HKEY_CURRENT_USER_LOCAL_SETTINGS = &H80000007
      End Enum
    
      Private Const MAX_REG_KEYNAME_SIZE = 255
      Private Const MAX_VALUE_NAME = 16383
      Dim achValue As New StringBuilder(MAX_VALUE_NAME - 1)
      Dim cchValue As UInteger
      Dim sc As New StringCollection
      Dim CountRegKey, CountRegValue As UInteger
      Dim Reg As RegistryKey
    
      Public Sub GetSubKeyNames(ByVal SubKey As String)
        Dim iKey, iValue, Result As Integer
        Dim SubhKey As IntPtr
        Dim lpname As New StringBuilder(MAX_REG_KEYNAME_SIZE + 1)
        Dim sSubkey As String
        Dim lpType As Integer
        Dim lpData As New StringBuilder(MAX_VALUE_NAME - 1)
        Dim lpcbData As Integer
    
        Try
          Result = RegOpenKeyEx(CType(RegHive.HKEY_CURRENT_USER, IntPtr), SubKey, 0, RegSam.KEY_ENUMERATE_SUB_KEYS Or RegSam.KEY_QUERY_VALUE, SubhKey)
          If Result <> 0 Then
            Throw New ApplicationException("Cannot access a closed registry key")
          End If
          cchValue = MAX_VALUE_NAME
          lpcbData = MAX_VALUE_NAME
          Do
            Result = RegEnumValue(SubhKey, iValue, achValue, cchValue, Nothing, lpType, lpData, lpcbData)
            If Result = 259 Then Exit Do
            sc.Add(achValue.ToString & "= " & lpType & " " & lpData.ToString)
            iValue += 1
            cchValue = MAX_VALUE_NAME
            lpcbData = MAX_VALUE_NAME
            CountRegValue += 1
          Loop
    
          Do
            Result = RegEnumKeyEx(SubhKey, iKey, lpname, MAX_REG_KEYNAME_SIZE + 1, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero)
            If Result = 259 Then Exit Do
            If SubKey <> String.Empty Then
              sSubkey = SubKey & "\" & lpname.ToString
            Else
              sSubkey = lpname.ToString
            End If
            sc.Add("[" & sSubkey & "]")
            CountRegKey += 1
            GetSubKeyNames(sSubkey)
            sSubkey = Replace(sSubkey, lpname.ToString, "")
            iKey += 1
          Loop
          RegCloseKey(SubhKey)
        Catch ex As Exception
    
        End Try
      End Sub
    
      Private Sub frmGetSubKeyName_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim Current As Date
        Dim Elap As TimeSpan
        Dim ans(-1) As String
    
        Reg = Registry.CurrentUser
        Current = Date.Now
    
        GetSubKeyNames("")
    
        If sc.Count > 0 Then
          ReDim ans(sc.Count - 1)
          sc.CopyTo(ans, 0)
        End If
        lboxInformation.Items.AddRange(ans)
        Me.Text = ans.Count
    
        Elap = Now.Subtract(Current)
        lblTime.Text = lblTime.Text & " " & Elap.TotalSeconds
        lblKey.Text = lblKey.Text & " " & CountRegKey
        lblValue.Text = lblValue.Text & " " & CountRegValue
      End Sub
    End Class

    Salam

    Xan To



    • Edited by Xan To Wednesday, January 15, 2014 8:42 AM
    Wednesday, January 15, 2014 8:25 AM
  • Hi Xan To

    Mohon maaf atas keterlambatan membalas forum ini

    Saya baru saja selesai mendiskusikan masalah ini dengan Carl Cai dan test kode yang kamu posting di thread berikut

    http://social.msdn.microsoft.com/Forums/en-US/779dcc26-a759-4771-bf77-cc4f0b65d974/how-to-get-the-value-when-value-type-is-regdword-and-regmultisz-with-regenumvalue-function?forum=vbgeneral

    Mohon dicoba kode berikut

    Silahkan membalas di forum ini atau di thread berbahasa Inggris, saya dan Carl Cai akan mencoba follow up case ini bersama sama

    Terima kasih 


    Andy Nugraha

    TechNet Community Support

    Tuesday, January 21, 2014 8:35 AM
  • Hi Xan to

    Selamat, karena masalah ini berhasil kamu selesaikan

    Boleh bantu kita posting jawaban kamu disini?

    Terima kasih


    Andy Nugraha

    TechNet Community Support

    Friday, January 24, 2014 1:31 AM
  • Hallo Andy terima kasih atas supportnya, baik saya akan pos codenya....

    untuk VB6 berikut kode programnya

    ' This code is licensed according to the terms and conditions listed here.
    ' Declarations and such needed for the example:
    ' (Copy them to the (declarations) section of a module.)
    Private Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal hkey _
        As Long, ByVal dwIndex As Long, ByVal lpValueName As String, lpcbValueName As Long, _
        ByVal lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long
    Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hkey _
        As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired _
        As Long, phkResult As Long) As Long
    Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hkey As Long) As Long
    Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (Destination As Any, _
        Source As Any, ByVal Length As Long)
    Const HKEY_LOCAL_MACHINE = &H80000002
    Const KEY_QUERY_VALUE = &H1
    Const REG_SZ = 1
    Const REG_BINARY = 3
    Const REG_DWORD = 4
    Const REG_MULTI_SZ = 7
    Const REG_EXPAND_SZ = 2
    Const REG_QWORD = 11
    Const HKEY_CURRENT_USER = &H80000001
    
    ' *** Place the following code inside a form window. ***
    Private Sub cmdRun_Click()
        Dim valuename As String     ' name of the value being retrieved
        Dim valuelen As Long        ' length of valuename
        Dim datatype As Long        ' receives data type of value
        Dim data(0 To 254) As Byte  ' 255-byte data buffer for read information
        Dim datalen As Long         ' size of data buffer information
        Dim datastring As String    ' will receive data converted to a string, if necessary
        Dim hkey As Long            ' handle to the registry key to enumerate the values of
        Dim index As Long           ' counter for the index of the value to enumerate
        Dim c As Long               ' counter variable
        Dim retval As Long          ' functions' return value
        
        ' Open the registry key to enumerate the values of.
        retval = RegOpenKeyEx(HKEY_CURRENT_USER, "Test\Test 2", _
            0, KEY_QUERY_VALUE, hkey)
        ' Check to see if an error occured.
        If retval <> 0 Then
            Debug.Print "Registry key could not be opened -- aborting."
            End  ' abort the program
        End If
        
        ' Begin enumerating the values.  Get each one, displaying its name.  If it's a null-
        ' terminated string or binary data, display it.  If not, say so.
        index = 0  ' initialize the counter
        While retval = 0  ' loop while successful
            ' Initialize the value name buffer.
            valuename = Space(255)  ' 255-space buffer
            valuelen = 255  ' length of the string
            datalen = 255  ' size of data buffer
            ' Get the next value to be enumerated
            retval = RegEnumValue(hkey, index, valuename, valuelen, 0, datatype, data(0), datalen)
            If retval = 0 Then  ' if successful, display information
                ' Extract the useful information from the value name buffer and display it.
                valuename = Left(valuename, valuelen)
                Debug.Print "Value Name: "; valuename
                ' Determine the data type of the value and display it.
                Select Case datatype
                Case REG_SZ  ' null-terminated string
                    ' Copy the information from the byte array into the string.
                    ' We subtract one because we don't want the trailing null.
                    datastring = Space(datalen - 1)  ' make just enough room in the string
                    CopyMemory ByVal datastring, data(0), datalen - 1  ' copy useful data
                    Debug.Print "  Data (string): "; datastring
                Case REG_BINARY  ' binary data
                    ' Display the hexadecimal values of each byte of data, separated by
                    ' sapces.  Use the datastring buffer to allow us to assure each byte
                    ' is represented by a two-character string.
                    Debug.Print "  Data (binary):";
                    For c = 0 To datalen - 1  ' loop through returned information
                        datastring = Hex(data(c))  ' convert value into hex
                        ' If needed, add leading zero(s).
                        If Len(datastring) < 2 Then datastring = _
                            String(2 - Len(datastring), "0") & datastring
                        Debug.Print " "; datastring;
                    Next c
                    Debug.Print  ' end the line
                Case REG_DWORD
                    Dim Longvalue As Long
                    Debug.Print "  Data (DWORD):";
                    CopyMemory Longvalue, data(0), datalen - 1
                    Debug.Print ""; Longvalue;
                    Debug.Print  ' end the line
                Case REG_MULTI_SZ
                    datastring = Space(datalen - 1)  ' make just enough room in the string
                    CopyMemory ByVal datastring, data(0), datalen - 1  ' copy useful data
                    Debug.Print "  Data (MULTI_SZ): "; Replace(datastring, Chr$(0), " ")
                Case REG_EXPAND_SZ
                    datastring = Space(datalen - 1)  ' make just enough room in the string
                    CopyMemory ByVal datastring, data(0), datalen - 1  ' copy useful data
                    Debug.Print "  Data (EXPAND_SZ): "; datastring
                Case REG_QWORD
                    Debug.Print "  Data (QWORD):";
                    For c = 0 To datalen - 1  ' loop through returned information
                        datastring = Hex(data(c))  ' convert value into hex
                        ' If needed, add leading zero(s).
                        If Len(datastring) < 2 Then datastring = _
                            String(2 - Len(datastring), "0") & datastring
                        Debug.Print " "; datastring;
                    Next c
                    Debug.Print  ' end the line
                Case Else  ' a data type this example doesn't handle
                    Debug.Print "This example doesn't know how to read that kind of data."
                End Select
            End If
            index = index + 1  ' increment the index counter
        Wend  ' end the loop
        
        ' Close the registry key.
        retval = RegCloseKey(hkey)
    End Sub
    
    Private Function TrimNull(startstr As String) As String
    On Error Resume Next
        iPos = InStr(startstr, Chr$(0))
        If iPos Then
           TrimNull = Left$(startstr, iPos - 1)
           Exit Function
        End If
        TrimNull = startstr
    End Function

    Hal yang perlu diperhatikan adalah untuk nilai kembalian dari lpData berupa Array, variabel yang digunakan adalah Any, saya gak tahu kenapa harus menggunakan Any, sy sudah coba menggunakan Byte atau Byte() tapi malah error.

    katakanlah sebuah Registry Isinya adalah
    Nama Value: New Value #1
    Type Value: REG_SZ
    Data Value: "kyyyyyy"

    Maka yang sebenarnya dikembalikan oleh lpData adalah Nilai ANSI dari k dan y:
    lpData(0)=107
    lpData(1)=121
    lpData(2)=121
    lpData(3)=121
    lpData(4)=121
    lpData(5)=121
    lpData(6)=121

    CopyMemory itu gunanya untuk mengubah Array ANSI menjadi String sehingga hasilnya "kyyyyyy"

    Sayangnya di VB.Net Variabel Any sudah tidak ada, beberapa orang menyarankan menggunakan StringBuilder sayangnya Stringbuilder tidak bisa memanipulasi data pada tipe registry REG_DWORD dan REG_MULTI_SZ sesuai dengan seharusnya, oleh karena itu kita harus menset-nya menjadi variabel Byte() jadi nilai yang dikembalikan oleh lpData pada RegEnumValue berupa Array Byte, hasilnya baru dimanipulasi secara manual sesuai dengan kebutuhan, berikut kode dalam VB.Net, semoga bermanfaat:

    <DllImport("advapi32.dll", SetLastError:=True)> _ Private Shared Function RegEnumValue(ByVal hKey As IntPtr, ByVal dwIndex As Integer, ByVal lpValueName As StringBuilder, ByRef lpcValueName As Integer, _ ByVal lpReserved As IntPtr, ByRef lpType As IntPtr, ByVal lpData As Byte(), ByRef lpcbData As IntPtr) As Integer End Function Private Const MAX_REG_KEYNAME_SIZE = 255 Private Const MAX_VALUE_NAME = 16383 Dim lpValueName As New StringBuilder(MAX_VALUE_NAME - 1) Dim lpcValueName As UInteger Dim sc As New StringCollection Dim CountRegKey, CountRegValue As UInteger Private Sub GetSubKeyNames(ByVal SubKey As String) Dim iKey, dwIndex, Result As Integer Dim SubhKey As IntPtr Dim lpname As New StringBuilder(MAX_VALUE_NAME - 1) Dim sSubkey As String Dim lpType As Integer Dim lpcbData As Integer Dim lpData(255) As Byte Dim value, Test, tmpValueName As String Try Result = RegOpenKeyEx(RegistryHive.CurrentUser, SubKey, 0, RegSam.KEY_ENUMERATE_SUB_KEYS Or RegSam.KEY_QUERY_VALUE, SubhKey) If Result <> 0 Then Throw New ApplicationException("Cannot access a closed registry key") End If lpcValueName = MAX_VALUE_NAME lpcbData = MAX_VALUE_NAME Do Result = RegEnumValue(SubhKey, dwIndex, lpValueName, lpcValueName, Nothing, lpType, lpData, lpcbData) If lpValueName.ToString = String.Empty Then tmpValueName = "@" Else tmpValueName = Chr(34) & lpValueName.ToString & Chr(34) ReDim Preserve lpData(lpcbData - 1) If Result = 259 Then Exit Do Select Case lpType Case RegType.REG_DWORD value = "" For index = 0 To lpcbData - 1 Test = Convert.ToString(lpData(index), 2) Test = New String("0", 8 - Test.Length) + Test value = Test + value Next Dim CResult = Convert.ToUInt32(value, 2) sc.Add(tmpValueName & "= " & lpType & " " & CResult.ToString) Case Else value = System.Text.ASCIIEncoding.ASCII.GetString(lpData) Test = value.Replace(ChrW(0), " ").Trim() sc.Add(tmpValueName & "= " & lpType & " " & Test.ToString) End Select dwIndex += 1 lpcValueName = MAX_VALUE_NAME lpcbData = MAX_VALUE_NAME ReDim lpData(lpcbData) CountRegValue += 1 Loop Do Result = RegEnumKeyEx(SubhKey, iKey, lpname, MAX_REG_KEYNAME_SIZE + 1, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero) If Result = 259 Then Exit Do If SubKey <> String.Empty Then sSubkey = SubKey & "\" & lpname.ToString Else sSubkey = lpname.ToString End If sc.Add("[" & sSubkey & "]") CountRegKey += 1 GetSubKeyNames(sSubkey) sSubkey = Replace(sSubkey, lpname.ToString, "") iKey += 1 Loop RegCloseKey(SubhKey) Catch ex As Exception End Try End Sub


    • Edited by Xan To Friday, January 24, 2014 7:42 AM
    • Marked as answer by Xan To Friday, January 24, 2014 8:06 AM
    Friday, January 24, 2014 7:40 AM
  • Hi Xan To

    Terima kasih atas postingan jawabannya


    Andy Nugraha

    TechNet Community Support

    Monday, January 27, 2014 1:54 AM