VB6阅读注册表条目,但没有返回数据



在这里新签约绝望的用户。

我很久以前就离开了编程业务,但随后被要求进行一些增强等。

我想使用注册表存储一些文件位置,以便用户不必始终指定它们。我想在hkey_local_machine下存储它们,因为有多个用户。

我已经使用regcreateKeyex创建了密钥,并使用regsetValueExstring输入了一个值,因此HKEY_LOCAL_MACHINE下有一个键称为SupplierFile,它具有" c:c: documents and Settings"的值。。

但是,当我使用regqueryValueExstring时,它不起作用:lpvalue字符串是空的,尽管CBDATA确实包含了我期望在那里找到的字符串的长度。错误的错误是234,error_more_data。

我尝试使用ReggetValue,因为我认为也许是一个非终止字符串是问题所在,但是我在API DLL中没有ReggetValue。

即使在如何用空的终止字符串的线路的线上,任何建议都将受到感激。谢谢,史蒂夫

您的错误表明您尚未初始化足够大的字符串缓冲区以用于API函数,但没有代码,?我从我使用的注册表公用事业类中拉下了代码。我认为我包括所有使用的API声明和常数,以及将返回错误转化为有用的方法。

Public Enum RegRootKey
    HKEY_CLASSES_ROOT = &H80000000
    HKEY_CURRENT_CONFIG = &H80000005
    HKEY_CURRENT_USER = &H80000001
    HKEY_DYN_DATA = &H80000006
    HKEY_LOCAL_MACHINE = &H80000002
    HKEY_PERFORMANCE_DATA = &H80000004
    HKEY_USERS = &H80000003
End Enum
'the following declare is used to return windows error descriptions
Private Declare Function FormatMessage Lib "Kernel32" Alias "FormatMessageA" (ByVal dwFlags As Long, lpSource As Any, ByVal dwMessageId As Long, ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, Arguments As Long) As Long
Private Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
Private Const FORMAT_MESSAGE_IGNORE_INSERTS = &H200
'key constants
Private Const ERROR_NO_MORE_ITEMS = 259&
Private Const ERROR_MORE_DATA = 234
Private Const ERROR_SUCCESS = 0&
Private Const SYNCHRONIZE = &H100000
Private Const READ_CONTROL = &H20000
Private Const READ_WRITE = 2
Private Const READAPI = 0
Private Const STANDARD_RIGHTS_ALL = &H1F0000
Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
Private Const STANDARD_RIGHTS_EXECUTE = (READ_CONTROL)
Private Const STANDARD_RIGHTS_READ = (READ_CONTROL)
Private Const STANDARD_RIGHTS_WRITE = (READ_CONTROL)
Private Const KEY_NOTIFY = &H10
Private Const KEY_QUERY_VALUE = &H1
Private Const KEY_CREATE_LINK = &H20
Private Const KEY_CREATE_SUB_KEY = &H4
Private Const KEY_ENUMERATE_SUB_KEYS = &H8
Private Const KEY_EVENT = &H1
Private Const KEY_SET_VALUE = &H2
Private Const KEY_ALL_ACCESS = ((STANDARD_RIGHTS_ALL Or KEY_QUERY_VALUE Or KEY_SET_VALUE Or KEY_CREATE_SUB_KEY Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY Or KEY_CREATE_LINK) And (Not SYNCHRONIZE))
Private Const KEY_READ = ((STANDARD_RIGHTS_READ Or KEY_QUERY_VALUE Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY) And (Not SYNCHRONIZE))
Private Const KEY_EXECUTE = ((KEY_READ) And (Not SYNCHRONIZE))
Private Const KEY_WRITE = ((STANDARD_RIGHTS_WRITE Or KEY_SET_VALUE Or KEY_CREATE_SUB_KEY) And (Not SYNCHRONIZE))
Private Const REG_OPTION_NON_VOLATILE = 0
Private Const REG_SZ = 1                         ' Unicode nul terminated string
Private Const REG_BINARY = 3
Private Const REG_DWORD = 4
Private Const REG_MULTI_SZ = 7                   ' Multiple Unicode strings
Private Const REG_NONE = 0                       ' No value type
Private Const KEY_WOW64_64KEY As Long = &H100& '32 bit app to access 64 bit hive
Private Const KEY_WOW64_32KEY As Long = &H200& '64 bit app to access 32 bit hive
'API declarations
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, 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 RootKeyName Lib "advapi32.dll" Alias "RootKeyNameA" (ByVal lphKey As RegRootKey) As String

Public Function GetStringValue(ByVal hKeyRoot As RegRootKey, ByVal hKeySubKey As String, ByVal ValueName As String, Optional ByVal Default As String) As String
    Dim strReturn As String
    Dim strBuffer As String
    Dim lngType As Long
    Dim lngBufLen As Long
    Dim lngRst As Long
    Dim hKeyHandle As Long
    On Error GoTo errGetStringValue
   'just to avoid any errors in calling functions using a ubound to check the contents
   strBuffer = String(255, vbNullChar)
   lngBufLen = Len(strBuffer)
   lngRst = RegOpenKeyEx(hKeyRoot, hKeySubKey, 0, KEY_READ Or KEY_WOW64_64KEY, hKeyHandle)
   If hKeyHandle <> 0 Then
       If StrComp(ValueName, "default", vbTextCompare) = 0 Then
           lngRst = RegQueryValueEx(hKeyHandle, "", ByVal 0&, lngType, ByVal strBuffer, lngBufLen)
       Else
           lngRst = RegQueryValueEx(hKeyHandle, ValueName, ByVal 0&, lngType, ByVal strBuffer, lngBufLen)
       End If
   End If
   If lngRst = 0 Then
       If lngType = REG_SZ Then
           If lngBufLen > 0 Then
               strReturn = Left$(strBuffer, lngBufLen - 1)
           Else
               strReturn = Default
           End If
       Else
           Err.Raise 1, App.EXEName, FormatClassError(1)
       End If
    ElseIf lngRst = 2 Then     'the key does not exists so return the default
        strReturn = Default
    Else  'if the return is non-zero there was an error
        Err.Raise lngRst, App.EXEName, "There was an error reading the " & RootKeyName(hKeyRoot) & "" & _
           hKeySubKey & " registry key, " & LCase$(FormatClassError(lngRst))
    End If
    If hKeyHandle <> 0 Then
        lngRst = RegCloseKey(hKeyHandle)
        hKeyHandle = 0
    End If
    GetStringValue = strReturn
    Exit Function
errGetStringValue:
    If hKeyHandle <> 0 Then
        lngRst = RegCloseKey(hKeyHandle)
        hKeyHandle = 0
    End If
    Err.Raise Err.Number, Err.Source & ":GetStringValue", Err.Description
End Function
Private Function FormatClassError(ByVal ErrorNumber As Long) As String
    Dim strReturn As String
    Dim strBuffer As String
    Dim lngBufLen As Long
    Dim lngRst As Long
    On Error Resume Next
    'initialize the buffer to to API function
    strBuffer = String(1024, vbNullChar)
    lngBufLen = Len(strBuffer)
    'make the call to the API function
    lngRst = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS, ByVal 0&, ErrorNumber, ByVal 0&, strBuffer, lngBufLen, ByVal 0&)
    'if the return value is <> 0 then we have a valid message
    If lngRst <> 0 Then
        strReturn = Left$(strBuffer, lngRst)
    Else
       'make another call to the API function with the last dll error
       lngRst = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS, ByVal 0&, Err.LastDllError, ByVal 0&, strBuffer, lngBufLen, ByVal 0&)
       If lngRst <> 0 Then
           strReturn = Left$(strBuffer, lngRst)
       Else
           strReturn = "Unable to retrieve error description."
       End If
    End If
    'return the result
    FormatClassError = strReturn
End Function

快速答案:在此处尝试getRegStringValue $代码

如果您(或其他)想了解更多

当您调用该API时,就像许多Windows API一样,您应该提供一个缓冲区(字符串)以保持注册表值,并且您应该通过缓冲区的最大尺寸传递。

msdn解释

如果LPDATA参数指定的缓冲区不足以容纳数据,则该功能返回error_more_data并将所需的缓冲区大小存储在LPCBDATA指向的变量中。在这种情况下,LPDATA缓冲区的内容不确定。

您需要分配一个缓冲区(可能充满了空间),然后通过LPDATA中的大小传递。

您应该先检查注册表是否确实存在。通过错误处理,我们可以检查注册表密钥输入。

Private Function RegOSInfo(RegPath As String, RegKey As String) As String
On Error GoTo ErrHandler

   Dim osName As String
   Dim Reg As Object
   Set Reg = CreateObject("WScript.Shell")
   RegOSInfo = Reg.RegRead(RegPath & "" & RegKey)

ErrHandler:
  RegOSInfo = "-555"  'custom Error Code, Registry key doesn't exist
End Function

您可以根据需要处理自定义错误代码。

最新更新