2014-10-14 6 views
-1

이 코드를 사용하여 레지스트리 키의 모든 값을 열거합니다. 여기액세스 위반 예외 RegEnumValue

Private ReadOnly HKeyLocalMachine As New IntPtr(-2147483646) 
    Private Const KeyQueryValueWow64Key As Integer = &H101 
    Private Const ErrorNoMoreItems As Integer = &H103 
    Private Const errorSuccess As Integer = &H0 

       Dim keyHandle As IntPtr = Nothing 
       RegOpenKeyEx(HKeyLocalMachine, newPath, 0, KeyQueryValueWow64Key, keyHandle) 

       If keyHandle = Nothing Then 
        Return "Error accessing registry key" 
       End If 

       Dim index As Integer = 0 
       Dim valueName As New StringBuilder(1000) 
       Dim valueLenght As UInteger 
       Dim valueDataLenght As IntPtr 

       If RegQueryInfoKey(keyHandle, Nothing, Nothing, Nothing, Nothing, Nothing,  Nothing, Nothing, valueLenght, valueDataLenght, Nothing, Nothing) = errorSuccess Then 
        Debug.WriteLine("SUCCESS IN REGQUERYINFOKEY") 
       End If 

        Do 
         returnValue = RegEnumValue(keyHandle, index, valueName, valueLenght, Nothing, Nothing, datalenght, valueDataLenght) 

        If returnValue = errorSuccess Then 
          Debug.WriteLine("Success") 
         End If 

        index = index + 1 
       Loop Until returnValue = ErrorNoMoreItems 

내 API 선언 있습니다 :

<DllImport("advapi32.dll", CharSet:=CharSet.Unicode)> _ 
    Private Shared Function RegOpenKeyEx(_ 
    hKey As IntPtr, _ 
    subKey As String, _ 
    ulOptions As Integer, _ 
    samDesired As Integer, _ 
    ByRef hkResult As IntPtr _ 
    ) As Integer 
    End Function 


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

<DllImport("advapi32.dll")> _ 
Private Shared Function RegQueryInfoKey(_ 
hkey As IntPtr, _ 
ByRef lpClass As StringBuilder, _ 
ByRef lpcbClass As UInteger, _ 
lpReserved As IntPtr, _ 
ByRef lpcSubKeys As UInteger, _ 
ByRef lpcbMaxSubKeyLen As UInteger, _ 
ByRef lpcbMaxClassLen As UInteger, _ 
ByRef lpcValues As UInteger, _ 
ByRef lpcbMaxValueNameLen As UInteger, _ 
ByRef lpcbMaxValueLen As IntPtr, _ 
ByRef lpcbSecurityDescriptor As UInteger, _ 
lpftLastWriteTime As IntPtr _ 
) As Integer 
End Function 

그리고 내가 널을 전달하면 내가, RegEnumValue null 이외의 마지막 매개 변수를 전달하면 함수가 성공하지만 INTPTR 난 AccessViolationException 받고 있어요 자료 없음 이름 만 검색합니다. 행운을 빌어 API 변수를 변경해 보았습니다. 다른 두 함수는 항상 성공했습니다.

+0

우리는 당신이 그 마지막 매개 변수를 전달하고 있는지 잘 모릅니다. 어떻게 든 그것을 보여주기 위해 생략했습니다. –

+0

RegQueryInfoKey 호출에서 값을 가져 오기 때문에 편집을 잊어 버렸습니다. – SomeNickName

+0

이 모든 작업을 수행하기 위해 관리되는 RegistryKey 클래스를 사용하지 않는 이유는 무엇입니까? –

답변

0

코드가 실패하는 이유는 사용자가 valueDataLenght을 초기화하지 않았기 때문입니다. 덧붙여,이 변수의 이름을 valueDataLength로 지정하십시오.

데이터 버퍼의 길이를 포함하는 DWORD을 참조하려면 IntPtr 변수 valueDataLength이 필요합니다. 여기 IntPtr을 사용하면 삶이 어려워집니다. 대신 다음과 같은 매개 변수를 선언 할 것입니다 :

ByRef lpcbData As Integer 
+0

같은 오류, http://i.imgur.com/r52yM4R.png – SomeNickName

+1

올바르게 입력하지 않았습니다. 나는 그 스크린 샷에서 당신이 잘못한 것을 볼 수 없습니다. 계속 노력해. –

+0

글쎄, 내 모든 코드를 게시하고 debug'ed 및 내가 뭘 잘못 볼 수 없습니다 ... – SomeNickName

관련 문제