【发布时间】:2022-01-03 05:19:23
【问题描述】:
我正在为非托管Offline Registry Library 编写一个基本的.NET 包装器。目前,我正在努力实现一个类 OfflineRegistryKey,它以 Microsoft.Win32.RegistryKey 为模型,但旨在用于离线 Registry Hives 而不是实时系统 Registry。
在尝试实现与 GetValueNames() 方法等效的方法(枚举注册表项中的值)时,我在尝试从 Offreg.dll 中 P/Invoke 非托管函数 OREnumValue 时遇到了一些麻烦。在这种情况下,我唯一感兴趣的参数是值的名称,或 lpValueName。
我的 OREnumValue 的 P/Invoke 代码:
[DllImport("Offreg.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern uint OREnumValue(
SafeRegistryHandle Handle,
uint dwIndex,
IntPtr lpValueName,
ref uint lpcValueName,
IntPtr lpType,
IntPtr lpData,
ref uint lpcbData);
我在我的代码中这样调用函数:
public class OfflineRegistryKey : IDisposable
{
private readonly SafeRegistryHandle hKey;
public string[] GetValueNames()
{
uint dwIndex = 0;
while (true)
{
uint lpcValueName = 0;
uint lpcbData = 0;
uint returnValue = OREnumValue(hKey, dwIndex, IntPtr.Zero, ref lpcValueName, IntPtr.Zero, IntPtr.Zero, ref lpcbData);
if (returnValue == 0x0103) // ERROR_NO_MORE_ITEMS
{
break;
}
else if (returnValue == 0x00EA) // ERROR_MORE_DATA
{
// Do stuff...
}
else
{
throw new Win32Exception(returnValue);
}
dwIndex++;
}
}
}
理想情况下,对 OREnumKey 的调用将返回 0xEA (ERROR_MORE_DATA),之后将再次调用它,直到到达结束索引并返回 0x103 (ERROR_NO_MORE_ITEMS)。
我得到的返回值(在运行时抛出异常并在循环的第一次迭代时停止执行)是0x57 (ERROR_INVALID_PARAMETER),这让我相信我以某种方式搞砸了 P /调用调用。如果对 P/Invoke 和 Windows API 有更深入了解的人可以为我提供一些指导,我将不胜感激。
谢谢!
【问题讨论】:
-
所有定义都在此处可用:github.com/LordMike/OffregLib/blob/master/OffregLib/… 不确定是否可以将 IntPtr.Zero 传递给 lpValueName 参数。
-
同意,您可能应该将其设为
[Out] StringBuilder lpValueName并传递一个 16383 个字符的 StringBuilder(尽管值名称通常不大于 260,请参阅 docs.microsoft.com/en-us/windows/win32/sysinfo/…) -
@SimonMourier 这正是我所需要的,谢谢!
标签: c# winapi runtime-error registry pinvoke