Registry.GetValue有什么问题?

时间:2011-03-10 16:39:47

标签: c# .net registry

我试图获得一个注册表值:

var value = Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography", "MachineGuid", 0);

在Windows XP中一切正常,但在Windows 7中返回0.在使用regedit的HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography中,我看到MachineGuid,但如果我运行

var keys = Registry.LocalMachine.OpenSubKey("SOFTWARE").OpenSubKey("Microsoft").OpenSubKey("Cryptography", RegistryKeyPermissionCheck.ReadSubTree).GetValueNames();

keys.Length为0。

我做错了什么?其他值都可以在OS中完成。

6 个答案:

答案 0 :(得分:23)

问题是您可能正在将解决方案编译为x86,如果编译为x64,则可以读取值。

尝试以下代码编译为x86和x64:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("MachineGUID:" + MachineGUID);

        Console.ReadKey();
    }

    public static string MachineGUID
    {
        get
        {
            Guid guidMachineGUID;
            if (Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Cryptography") != null)
            {
                if (Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Cryptography").GetValue("MachineGuid") != null)
                {
                    guidMachineGUID = new Guid(Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Cryptography").GetValue("MachineGuid").ToString());
                    return guidMachineGUID.ToString();
                }
            }
            return null;
        }
    }
}

您可以阅读有关Accessing an Alternate Registry View的更多信息。

您可以在here中找到一种在x86和x64中读取值的方法。

答案 1 :(得分:7)

它可能与UAC(用户帐户控制)有关。 Windows Vista和Windows 7的额外保护层。

您需要向注册管理机构申请权限。

修改: 你的代码现在:

var keys = Registry.LocalMachine.OpenSubKey("SOFTWARE")
    .OpenSubKey("Microsoft")
    .OpenSubKey("Cryptography", RegistryKeyPermissionCheck.ReadSubTree)
    .GetValueNames();

只请求Cryptography子项上的权限,可能会导致问题(至少我有一次),所以新代码将是:

var keys = Registry.LocalMachine.OpenSubKey("SOFTWARE", RegistryKeyPermissionCheck.ReadSubTree)
    .OpenSubKey("Microsoft", RegistryKeyPermissionCheck.ReadSubTree)
    .OpenSubKey("Cryptography", RegistryKeyPermissionCheck.ReadSubTree)
    .GetValueNames();

<强> EDIT2:
我在这段代码上附加了调试器:

var key1 = Registry.LocalMachine.OpenSubKey("SOFTWARE", RegistryKeyPermissionCheck.ReadSubTree);
var key2 = key1.OpenSubKey("Microsoft", RegistryKeyPermissionCheck.ReadSubTree);
var key3 = key2.OpenSubKey("Cryptography", RegistryKeyPermissionCheck.ReadSubTree);
var key4 = key3.GetValueNames();

事实证明,您可以读取该特定值,至少是我的猜测,因为所有数据都是正确的,直到我打开key3,ValueCount为零,而不是预期的1。

我认为这是一个受保护的特殊价值。

答案 2 :(得分:6)

你说你在使用64位Windows:你的应用程序是32位吗?如果是这样,它可能会受到registry redirection的影响并正在查看HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Cryptography。您可能需要P / Invoke来解决它:http://msdn.microsoft.com/en-us/library/aa384129.aspx

答案 3 :(得分:3)

如果您不是管理员,则您只拥有HKLM的读取权限。您需要以只读方式打开密钥。不知道如何使用.NET的Registry类做到这一点;使用API​​直接使用RegOpenKeyEx()KEY_READ标记。

编辑:检查MSDN后,我看到OpenSubKey()打开只读,如果成功则返回内容,如果失败则返回任何内容。由于您正在链接多个OpenSubKey调用,因此很可能其中一个失败会导致其他调用失败。尝试将它们分解为单独的调用,并检查返回的中间值。

答案 4 :(得分:0)

聚会可能有点晚了,但是,没有一个解决方案对我有用。

我是这样解决这个问题的:

public static Guid GetMachineGuid
    {
        get
        {
            var machineGuid = Guid.Empty;

            var localMachineX64View = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
            var cryptographySubKey = localMachineX64View.OpenSubKey(@"SOFTWARE\Microsoft\Cryptography");
            
            if (cryptographySubKey == null) return machineGuid;
            
            var machineGuidValue = (string)cryptographySubKey.GetValue("MachineGuid");

            Guid.TryParse(machineGuidValue, out machineGuid);

            return machineGuid;
        }
    }

答案 5 :(得分:-1)

我在导入 Microsoft.Win32 并将应用程序设置更改为 x64 时解决了该问题,如提到的 pedrocgsousa。