0
DWORD OREnumValue(
  __in         ORHKEY Handle,
  __in         DWORD dwIndex,
  __out        PWSTR lpValueName,
  __inout      PDWORD lpcValueName,
  __out_opt    PDWORD lpType,
  __out_opt    PBYTE lpData,
  __inout_opt  PDWORD lpcbData
);

我的代码:

public static extern uint OREnumValue(IntPtr Handle, uint dwIndex, [MarshalAsAttribute(UnmanagedType.LPWStr)] out StringBuilder lpValueName, ref int lpcValueName, out uint lpType, out IntPtr lpData, ref int lpcbData);

    IntPtr Handle=mykey;
    uint dwIndex=0;

    StringBuilder lpValueName = new StringBuilder(16383);
    int lpcValueName=lpValueName.Capacity;  

    uint lpType=0;
    IntPtr lpData;
    int lpcbData = int.MaxValue;

    uint ret3= OREnumValue(Handle, dwIndex, out lpValueName, ref lpcValueName, out lpType, out lpData, ref lpcbData);

这给出了一个错误:

ret3=ERROR_MORE_DATA 259

我认为问题出在

  1. lpData - 我应该为 PBYTE 使用什么?或者
  2. lpcbData - 我应该使用什么容量?

来自 MSDN

如果 lpData 指定的缓冲区不足以容纳数据,则函数返回 ERROR_MORE_DATA 并将所需的缓冲区大小存储在 lpcbData 指向的变量中。在这种情况下,lpData 的内容是未定义的。

4

2 回答 2

1

您永远不应该明确定义字符串构建器的长度,该值应该使用 RegQueryInfoKey 方法获得,该方法将为您提供最长值名称、子键名称和值数据的字节长度,然后您可以使用它们来初始化字符串接收实际名称和数据的构建器和字节数组。这意味着您使用的内存量尽可能少,同时仍然足够大以包含结果。我很确定您的问题在于您为 lpValueName 定义的长度。

此外,您应该使用 UIntPtr 而不是 IntPtr,如果您需要数据,lpData 字段应该是字节数组。

于 2013-07-26T15:31:36.213 回答
0

根据以下来源,您应该将 IntPtr 用于 PBYTE:

(这些不适用于您的 api,但也使用 PBYTE。如果您将来自 msdn 的 c++ 值与列出的链接进行比较)

您很可能需要定义

    var myIntPtr = Marshal.AllocCoTaskMem(sizeOfMyIntPtr);
于 2019-01-09T12:57:24.843 回答