Registry.LocalMachine.OpenSubKey(regPath);在.NET 3.5环境中返回NULL

时间:2015-08-03 06:36:13

标签: c# .net windows registry

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

string regPath = "Software\\Bentley\\AutoPIPE\\V8i Ribbon and Reporting";

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

我尝试了不同的方法,例如this onethis,但我遇到了同样的错误:

  

对象引用未设置为Object的实例。

它始终在ribbonKey中返回null,但是密钥存在于注册表中。我搜索了这个主题并找到了很多解决方案,但即使this也无法帮助我,因为我正在使用.NET 3.5

任何帮助都将受到高度赞赏。

2 个答案:

答案 0 :(得分:1)

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

http://www.sitepoint.com/real-time-apps-laravel-5-1-event-broadcasting/

答案 1 :(得分:1)

这可能是因为注册表具有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框架对您很重要 - 您应该使用一些技巧。我在这里找到了它:What are some alternatives to RegistryKey.OpenBaseKey in .NET 3.5?

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);