gpt4 book ai didi

c# - HKEY 到 Microsoft.Win32.RegistryKey 的转换

转载 作者:可可西里 更新时间:2023-11-01 09:47:53 25 4
gpt4 key购买 nike

我有一个使用 RegOpenKeyEx (WinApi) 开放的注册表 HKEY。现在我想将 HKEY 转换为对象 Microsoft.Win32.RegistryKey。这将允许我使用更方便的 .Net 操作来进一步处理此 key 。

您知道如何以可靠的方式为 C# .Net 2.0 而非更高版本完成此转换吗?

感谢您的帮助!

我尝试使用反射访问 RegistryKey.GetBaseKey(hKey) 以将 HKEY 转换为 RegistryKey 但失败了:

[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int RegOpenKeyEx(IntPtr hKey, string subKey, int ulOptions, int samDesired, out IntPtr phkResult);

public enum RegWow64Options
{
None = 0,
KEY_WOW64_64KEY = 0x0100,
KEY_WOW64_32KEY = 0x0200
}

public enum RegRights
{
ReadKey = 131097,
WriteKey = 131078
}

static void exampleTransformKeytoRegistryKey()
{
IntPtr hKeyChild;
IntPtr hKeyParent = getRegistryKeyHandle(Registry.LocalMachine);

if (hKeyParent != IntPtr.Zero)
{
int result = RegOpenKeyEx(
getRegistryKeyHandle(Registry.LocalMachine),
@"SOFTWARE\Microsoft",
0,
((int)RegRights.ReadKey) | ((int)RegWow64Options.KEY_WOW64_64KEY),
out hKeyChild);

if (result == 0)
{
// hKeyChild has been retrieved
// now convert hKeyChild to RegistryKey keyChild

Type keyType = typeof(RegistryKey);
RegistryKey keyChild = (RegistryKey)keyType.InvokeMember(
"GetBaseKey",
System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static,
null,
keyType,
new object[] { hKeyChild });

// work with keyChild...
}
}
}

static IntPtr getRegistryKeyHandle(RegistryKey registryKey)
{
Type registryKeyType = typeof(RegistryKey);
System.Reflection.FieldInfo fieldInfo =
registryKeyType.GetField("hkey", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

SafeHandle handle = (SafeHandle)fieldInfo.GetValue(registryKey);
IntPtr dangerousHandle = handle.DangerousGetHandle();
return dangerousHandle;
}

更新:以下方法(在某种程度上)会起作用。请关注函数getKeyToRegistryKey。

[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int RegOpenKeyEx(IntPtr hKey, string subKey, int ulOptions, int samDesired, out IntPtr phkResult);

public enum RegWow64Options
{
None = 0,
KEY_WOW64_64KEY = 0x0100,
KEY_WOW64_32KEY = 0x0200
}

public enum RegRights
{
ReadKey = 131097,
WriteKey = 131078
}

static void exampleTransformKeytoRegistryKey2()
{
IntPtr hKeyChild;
IntPtr hKeyParent = getRegistryKeyHandle(Registry.LocalMachine);

if (hKeyParent != IntPtr.Zero)
{
int result = RegOpenKeyEx(
getRegistryKeyHandle(Registry.LocalMachine),
@"SOFTWARE\Microsoft",
0,
((int)RegRights.ReadKey) | ((int)RegWow64Options.KEY_WOW64_32KEY),
out hKeyChild);

if (result == 0)
{
// hKeyChild has been retrieved
// now convert hKeyChild to RegistryKey keyChild
RegistryKey keyChild = getKeyToRegistryKey(hKeyChild, false, true);

// work with keyChild...
}
}
}

static RegistryKey getKeyToRegistryKey(IntPtr hKey, bool writable, bool ownsHandle)
{
//Get the BindingFlags for private contructors
System.Reflection.BindingFlags privateConstructors = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic;
//Get the Type for the SafeRegistryHandle
Type safeRegistryHandleType = typeof(Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid).Assembly.GetType("Microsoft.Win32.SafeHandles.SafeRegistryHandle");
//Get the array of types matching the args of the ctor we want
Type[] safeRegistryHandleCtorTypes = new Type[] { typeof(IntPtr), typeof(bool) };
//Get the constructorinfo for our object
System.Reflection.ConstructorInfo safeRegistryHandleCtorInfo = safeRegistryHandleType.GetConstructor(
privateConstructors, null, safeRegistryHandleCtorTypes, null);
//Invoke the constructor, getting us a SafeRegistryHandle
Object safeHandle = safeRegistryHandleCtorInfo.Invoke(new Object[] { hKey, ownsHandle });

//Get the type of a RegistryKey
Type registryKeyType = typeof(RegistryKey);
//Get the array of types matching the args of the ctor we want
Type[] registryKeyConstructorTypes = new Type[] { safeRegistryHandleType, typeof(bool) };
//Get the constructorinfo for our object
System.Reflection.ConstructorInfo registryKeyCtorInfo = registryKeyType.GetConstructor(
privateConstructors, null, registryKeyConstructorTypes, null);
//Invoke the constructor, getting us a RegistryKey
RegistryKey resultKey = (RegistryKey)registryKeyCtorInfo.Invoke(new Object[] { safeHandle, writable });
//return the resulting key
return resultKey;
}

static IntPtr getRegistryKeyHandle(RegistryKey registryKey)
{
Type registryKeyType = typeof(RegistryKey);
System.Reflection.FieldInfo fieldInfo =
registryKeyType.GetField("hkey", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

SafeHandle handle = (SafeHandle)fieldInfo.GetValue(registryKey);
IntPtr dangerousHandle = handle.DangerousGetHandle();
return dangerousHandle;
}

这种方法的问题在于它只能在纯 .Net 2.0 应用程序中工作。如果您在 .Net 2.0 DLL 中使用代码并尝试从 .Net 4.0 应用程序中使用它,代码将失败。因此,我仍然希望找到另一种适用于混合环境的解决方案。

最佳答案

使用 RegistryKey.FromHandle(new SafeRegistryHandle(handle,true));

关于c# - HKEY 到 Microsoft.Win32.RegistryKey 的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21194539/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com