CSharp - 在. NET 3.5环境中,C# Registry.LocalMachine.OpenSubKey(regPath); 返回 NULL

  显示原文与译文双语对照的内容

我正在尝试使用以下命令访问注册表:


string regPath ="SoftwareBentleyAutoPIPEV8i Ribbon and Reporting";



RegistryKey ribbonKey = Registry.LocalMachine.OpenSubKey(regPath);



在这个例子中,我尝试了不同的方法:换句话说,这个,但我也遇到同样的错误:

未将对象引用设置到对象的实例。

它总是在 ribbonKey 中返回空值,但是注册表中的键存在。 我已经搜索了这个主题,找到了很多解决方案,但是即使是 ,因为我正在使用,所以无法帮助我。

任何帮助都将非常感激。

时间: 原作者:

你正在运行什么系统? 必须尝试这个小的解决方案?

我可以在 regedit.exe 中看到的注册表项返回 OpenSubKey() null 。

原作者:

这可能是因为注册表有不同的x32和x64键。 使用 3.5框架对你来说是否重要? 如果没有- 你可以将它更改为 4.0并使用以下代码:


var regView = Environment.Is64BitOperatingSystem? RegistryView.Registry64 : RegistryView.Registry32;


var registry = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, regView);



var keyPath = @"SoftwareBentleyAutoPIPEV8i Ribbon and Reporting";


var key = registry.OpenSubKey(keyPath);



如果 3.5框架对你很重要- 你应该使用一些技巧。 我在这里发现了:在. NET 3.5中是什么替代的RegistryKey.OpenBaseKey


public static class RegistryExtensions


{



 public enum RegistryHiveType


 {


 X86,


 X64


 }



 static Dictionary<RegistryHive, UIntPtr> _hiveKeys = new Dictionary<RegistryHive, UIntPtr> 


 {


 { RegistryHive.ClassesRoot, new UIntPtr(0x80000000u) },


 { RegistryHive.CurrentConfig, new UIntPtr(0x80000005u) },


 { RegistryHive.CurrentUser, new UIntPtr(0x80000001u) },


 { RegistryHive.DynData, new UIntPtr(0x80000006u) },


 { RegistryHive.LocalMachine, new UIntPtr(0x80000002u) },


 { RegistryHive.PerformanceData, new UIntPtr(0x80000004u) },


 { RegistryHive.Users, new UIntPtr(0x80000003u) }


 };



 static Dictionary<RegistryHiveType, RegistryAccessMask> _accessMasks = new Dictionary<RegistryHiveType, RegistryAccessMask> 


 {


 { RegistryHiveType.X64, RegistryAccessMask.Wow6464 },


 { RegistryHiveType.X86, RegistryAccessMask.WoW6432 }


 };



 [Flags]


 public enum RegistryAccessMask


 {


 QueryValue = 0x0001,


 SetValue = 0x0002,


 CreateSubKey = 0x0004,


 EnumerateSubKeys = 0x0008,


 Notify = 0x0010,


 CreateLink = 0x0020,


 WoW6432 = 0x0200,


 Wow6464 = 0x0100,


 Write = 0x20006,


 Read = 0x20019,


 Execute = 0x20019,


 AllAccess = 0xF003F


 }



 [DllImport("advapi32.dll", CharSet = CharSet.Auto)]


 public static extern int RegOpenKeyEx


 (


 UIntPtr hKey,


 string subKey,


 uint ulOptions,


 uint samDesired,


 out IntPtr hkResult


 );



 public static RegistryKey OpenBaseKey(RegistryHive registryHive, RegistryHiveType registryType)


 {


 int result = -1;


 UIntPtr hiveKey = _hiveKeys[registryHive];


 if (Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version.Major> 5)


 {


 RegistryAccessMask flags = RegistryAccessMask.QueryValue | RegistryAccessMask.EnumerateSubKeys | RegistryAccessMask.Read;


 IntPtr keyHandlePointer = IntPtr.Zero;


 result = RegOpenKeyEx(hiveKey, String.Empty, 0, (uint) flags, out keyHandlePointer);


 if (result == 0)


 {


 var safeRegistryHandleType = typeof (SafeHandleZeroOrMinusOneIsInvalid).Assembly.GetType("Microsoft.Win32.SafeHandles.SafeRegistryHandle");


 var safeRegistryHandleConstructor = safeRegistryHandleType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] {typeof (IntPtr), typeof (bool)}, null);//.NET <4


 if (safeRegistryHandleConstructor == null)


 safeRegistryHandleConstructor = safeRegistryHandleType.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, new[] {typeof (IntPtr), typeof (bool)}, null);//.NET> = 4


 var keyHandle = safeRegistryHandleConstructor.Invoke(new object[] {keyHandlePointer, true});


 var net3Constructor = typeof (RegistryKey).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] {safeRegistryHandleType, typeof (bool)}, null);


 var net4Constructor = typeof (RegistryKey).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] {typeof (IntPtr), typeof (bool), typeof (bool), typeof (bool), typeof (bool)}, null);


 object key;


 if (net4Constructor!= null)


 key = net4Constructor.Invoke(new object[] {keyHandlePointer, true, false, false, hiveKey == _hiveKeys[RegistryHive.PerformanceData]});


 else if (net3Constructor!= null)


 key = net3Constructor.Invoke(new object[] {keyHandle, true});


 else


 {


 var keyFromHandleMethod = typeof (RegistryKey).GetMethod("FromHandle", BindingFlags.Static | BindingFlags.Public, null, new[] {safeRegistryHandleType}, null);


 key = keyFromHandleMethod.Invoke(null, new object[] {keyHandlePointer});


 }


 var field = typeof (RegistryKey).GetField("keyName", BindingFlags.Instance | BindingFlags.NonPublic);


 if (field!= null)


 field.SetValue(key, String.Empty);


 return (RegistryKey) key;


 }


 else if (result == 2)//The key does not exist.


 return null;


 throw new Win32Exception(result);


 }


 return null;


 }


}



用法示例:


var key64 = RegistryExtensions.OpenBaseKey(RegistryHive.LocalMachine, RegistryExtensions.RegistryHiveType.X64);


var keyPath = @"SoftwareBentleyAutoPIPEV8i Ribbon and Reporting";


var key = key64.OpenSubKey(keyPath);



原作者:
...