Registry.LocalMachine.OpenSubKey (regPath);在.net 3.5环境中返回NUL
本文关键字:环境 NUL 返回 net OpenSubKey LocalMachine regPath Registry | 更新日期: 2023-09-27 18:06:13
我试图使用以下命令访问注册表:
string regPath = "Software''Bentley''AutoPIPE''V8i Ribbon and Reporting";
RegistryKey ribbonKey = Registry.LocalMachine.OpenSubKey(regPath);
我尝试过不同的方法,即这个和这个,但我面临同样的错误:
对象引用未设置为对象的实例。
它总是在ribbonKey
中返回null,但是键存在于注册表中。我已经搜索了这个主题,并找到了许多解决方案,但即使这也不能帮助我,因为我使用.NET 3.5
。
您运行的是什么系统?必须尝试这个小方法吗?
OpenSubKey()为注册表项返回null,我可以在regedit.exe
这可能是因为x32和x64的注册表有不同的键。使用3.5框架对你来说很重要吗?如果没有,您可以将其更改为4.0,并使用以下代码:
var regView = Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32;
var registry = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, regView);
var keyPath = @"Software''Bentley''AutoPIPE''V8i Ribbon and Reporting";
var key = registry.OpenSubKey(keyPath);
如果3.5框架对你很重要-你应该使用一些技巧。我发现它在这里:什么是一些替代RegistryKey。.NET 3.5中的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 = @"Software''Bentley''AutoPIPE''V8i Ribbon and Reporting";
var key = key64.OpenSubKey(keyPath);