Предпринята попытка чтения или записи защищенной памяти. Это часто указывает на то, что другая память повреждена
Я использую следующий код
Эта ошибка возникает :
Попытка чтения или записи защищенной памяти. Это часто указывает на то, что другая память повреждена.
Предпринята попытка чтения или записи защищенной памяти. Это часто указывает на то, что другая память повреждена.
Public Class FormRegEnumValue
Private Const ERROR_SUCCESS = 0&
Private Const ERROR_NO_MORE_ITEMS = 259&
Private Const HKEY_CURRENT_USER = &H80000001
Private Const REG_BINARY = 3
Private Const REG_DWORD = 4
Private Const REG_EXPAND_SZ = 2
Private Const REG_SZ = 1
Private Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpValueName As String, ByVal lpcbValueName As Long, ByVal lpReserved As Long, ByVal lpType As Long, ByVal lpData As Object, ByVal lpcbData As Long) As Long
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal phkResult As Long) As Long
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim hKey As Long, num As Long, strName As String
Dim strData As String, Retval As Long, RetvalData As Long
Const Buffer As Long = 255
num = 0
strName = Space(Buffer)
strData = Space(Buffer)
Retval = Buffer
RetvalData = Buffer
If RegOpenKey(HKEY_CURRENT_USER, "Control PanelDesktop", hKey) = 0 Then 'error
While RegEnumValue(hKey, num, strName, Retval, 0, 0&, strData, RetvalData) <> ERROR_NO_MORE_ITEMS
If RetvalData > 0 Then
ListBox1.Items.Add(strName + Retval + " = " + strData + RetvalData - 1)
End If
num = num + 1
strName = Space(Buffer)
strData = Space(Buffer)
Retval = Buffer
RetvalData = Buffer
End While
RegCloseKey(hKey)
Else
ListBox1.Items.Add("Error")
End If
End Sub
End Class
Пожалуйста, покажи мне правильный путь
2 ответов:
Это, как правило, вызвано неправильным
Private Declare Functionзаявление. Типы, перечисленные в API Windows, отличаются от типов, используемых в коде VB или C#. Это большой список преобразования типов данных между Windows API и .Сети: API-интерфейса Win32 C++ для .ЧистаяНа сайтеPInvoke часто указан правильный VB-код.
Для RegEnumValue , исправьте типы данных, и
lpcValueNameявляется ByRef, а не ByVal:Declare Auto Function RegEnumValue Lib "Advapi32" ( _ ByVal hKey As IntPtr, _ ByVal dwIndex As Integer, _ ByVal lpValueName As StringBuilder, _ ByRef lpcValueName As Integer, _ ByVal lpReserved As IntPtr, _ ByVal lpType As IntPtr, _ ByVal lpData As IntPtr, _ ByVal lpcbData As IntPtr _ ) As IntegerДля RegCloseKey , просто исправить типы данных:
Declare Function RegCloseKey Lib "advapi32.dll" ( _ ByVal hKey As UIntPtr _ ) As IntegerДля RegOpenKey , исправьте типы данных и измените phkResult на ByRef:
Поэтому ваша функция должна выглядеть примерно так. К сожалению, я не знаю, что писать дляPrivate Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" ( _ ByVal hKey As Integer, _ ByVal lpSubKey As String, _ ByRef phkResult As IntPtr _ ) As IntegerstrDataилиRetvalData. Я добавил в блокTry/Finally, который будет уверен, чтоRegCloseKeyвызывается, даже если возникает ошибка. Вы хотите убедиться, что всегда закрываете вещи, особенно если что-то идет не так.Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Const Buffer As Long = 255 Dim hKey As IntPtr = IntPtr.Zero Dim num As Integer = 0 Dim strName As New StringBuilder Dim strData As IntPtr = ' I'm not surte what goes here. Dim Retval As Integer = Buffer Dim RetvalData As IntPtr = ' I'm not surte what goes here. If RegOpenKey(HKEY_CURRENT_USER, "Control Panel\Desktop", hKey) = 0 Then 'error Try While RegEnumValue(hKey, num, strName, Retval, IntPtr.Zero, IntPtr.Zero, strData, RetvalData) <> ERROR_NO_MORE_ITEMS If RetvalData > 0 Then ListBox1.Items.Add(strName.ToString + Retval + " = " + strData + RetvalData - 1) End If num = num + 1 strName = New StringBuilder(Buffer) strData = ' I'm not sure what goes here. Retval = Buffer RetvalData = ' I'm not surte what goes here. End While Finally RegCloseKey(hKey) End Try Else ListBox1.Items.Add("Error") End If End Sub
Используйте функциональные возможности, содержащиеся во встроенном Microsoft.Win32.Вместо этого пространство имен реестра.
Вы можете найти ссылку и множество примеров в MSDN.
Обновить
Если вам нужно использовать API, то подпись RegEnumValue должна быть изменена на что-то вроде:
Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA"(ByVal hKey As Integer, ByVal dwIndex As Integer, ByVal lpValueName As String, ByRef lpcbValueName As Integer, ByVal lpReserved As Integer, ByRef lpType As Integer, ByRef lpData As StringBuilder, ByRef lpcbData As Integer) As IntegerЗатем измените тип strData на StringBuilder и создайте новый экземпляр StringBuilder, в котором вы в данный момент заполняете strData пространства:
Возможно, потребуется внести и другие изменения, но пока это самое важное.strData = New StringBuilder(buffer)Обновление 2
Другие объявления должны иметь свои длинные значения, измененные на целочисленные, и результирующий параметр для RegOpenKey-ByRef:
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Integer) As Integer Private Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal hKey As Integer, ByVal lpSubKey As String, ByRef phkResult As Integer) As IntegerОбновление 3
Просмотрев мой старый API-код, я обнаружил, что вам нужно сделать довольно много дополнительной работы, чтобы обработать результаты:
Как только вы определили, что RegEnumValue прошел успешно (возвращаемое значение 0), вам нужно обработать результаты на основе параметра 3 from the end (lpType), который подскажет вам тип данных.
Затем, основываясь на типе (например, REG_SZ, REG_DWORD и т. д.), Вам нужно будет вызвать один из методов API RegQueryValueExA:
Declare Function RegQueryValueExString Lib "advapi32.dll" Alias "RegQueryValueExA"(ByVal hKey As Integer, ByVal lpValueName As String, ByVal lpReserved As Integer, ByRef lpType As Integer, ByVal lpData As String, ByRef lpcbData As Integer) As Integer Declare Function RegQueryValueExLong Lib "advapi32.dll" Alias "RegQueryValueExA"(ByVal hKey As Integer, ByVal lpValueName As String, ByVal lpReserved As Integer, ByRef lpType As Integer, ByRef lpData As Integer, ByRef lpcbData As Integer) As IntegerИ т. д. для того, чтобы получить значение в записи реестра.
Comments