无法在 C# 中取消引用 IntPtr
本文关键字:取消 引用 IntPtr | 更新日期: 2023-09-27 18:37:10
我写了一个在COM中实现IGroupPolicyObject Interface的类。其中一个方法现在在 C# 中返回 IntPtr 对象:
IntPtr ghKey = objectGPolicy.GetRegistryKey(GpoSectionMachine);
我想在使用属于Microsot.Win32命名空间的RegistryKey对象时取消引用该指针。
这不起作用:
(RegistryKey)ghKey = rootKey.CreateSubKey(policyPath);
我找不到如何取消对 Intptr 的引用。有人可以帮忙吗?
谢谢
IGroupPolicyObject.GetRegistryKey
不返回 .NET RegistryKey
对象,它返回 Win32 注册表项句柄(HKEY
)。对于包含本机 HKEY 的 IntPtr
值,可以执行两项有用的操作。首先,可以将其传递给其他 Win32 注册表访问函数。如果以这种方式使用它,则还需要在完成后通过调用RegCloseKey
来手动关闭它,否则它将泄漏句柄。
正如@HansPassant在他的评论中有帮助地指出的那样,您的第二个(可能更好)选择是将其转换为SafeRegistryHandle
并使用它来获取RegistryKey
对象:
var hkey = gpo.GetRegistryKey(GpoSectionMachine);
var safeHandle = new SafeRegistryHandle(hkey, true);
var reg = RegistryKey.FromHandle(safeHandle);
如果您编写了 IGroupPolicyObject
的托管实现,并且它从此函数返回实际的 RegistryKey
对象,则:
- 你做错了,你的实现不能移植到
IGroupPolicyObject
的任何其他消费者,并且 - 您必须在实现中手动将
RegistryKey
对象编组到IntPtr
中,因此只需执行相反的操作即可将其重新取出。(但实际上 - 不要这样做,你通过返回错误的类型来破坏 COM 协定。
应该编写此方法的实现以返回SafeRegistryHandle
(我相信封送拆收器会自动在SafeHandle
和非托管句柄之间进行转换)。 RegistryKey.Handle
就是其中之一,因此你可以一直使用 C# 类,直到需要从实现中返回一些内容。