Registry.GetValue总是返回null

28

我在注册表中有以下的键值:

路径为:HKEY_LOCAL_MACHINE\SOFTWARE\RSA,其中有一个名称为WebExControlManagerPath的值对象,其值为c:\

我想要做的是:

var r = Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\RSA", "WebExControlManagerPth",null);

if(r!=null)
    ProcessAsUser.Launch(ToString());

但是r的值总是为null。

输入图像描述

有什么想法吗?


我尝试了这个,它也返回了 Null。 - MoShe
8个回答

69

Jasonstatement是正确的,操作系统是问题所在,以下代码将帮助您解决。

RegistryKey localKey;
if(Environment.Is64BitOperatingSystem)
    localKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
else
    localKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);

string value = localKey.OpenSubKey("RSA").GetValue("WebExControlManagerPth").ToString();

2
无需编译“Any CPU”即可进行优秀的修复...这应该是最佳答案。 - dodgy_coder
1
@Ignatius,我没有检查过低于.NET 4.0的版本。谢谢你的信息 :) - Palanikumar
太棒了,如果您需要在.NET 4.0之前获得支持,请查看另一篇文章的答案 - James R
这是解决方案。 - SpiDey
我对这类事情非常谨慎,所以在调用“localKey.OpenSubKey…”之前,我添加了以下内容:if (localKey.GetSubKeyNames().Contains("RSA") && localKey.OpenSubKey("RSA").GetValueNames().Contains("WebExControlManagerPth")) value = localKey.OpenSubKey("RSA").GetValue("WebExControlManagerPth").ToString(); - Ted O'Connor

25

在C#中访问HKEY_LOCAL_MACHINE不同于批处理脚本的方式。您应该使用Registry.LocalMachine来调用:

RegistryKey myKey = Registry.LocalMachine.OpenSubKey( @"Software\RSA", false);
String value = (String)myKey.GetValue("WebExControlManagerPth");

if (!String.IsNullOrEmpty(value))
{
    ProcessAsUser.Launch(ToString());
}

更新:

如果它返回 null,请将你的构建架构设置为 Any CPU。操作系统可能以不同的方式虚拟化 32 位和 64 位的注册表。参见:http://msdn.microsoft.com/zh-cn/library/windows/desktop/aa965884%28v=vs.85%29.aspx从 32 位应用程序读取 64 位注册表http://msdn.microsoft.com/zh-cn/library/windows/desktop/ms724072%28v=vs.85%29.aspx


1
你有管理员权限吗?本地机器需要管理员权限才能写入。我不确定阅读是否需要管理员权限,但它可能是你空字符串的原因。JK,对我来说也是 null。 - Jason
我以管理员身份运行Visual Studio - MoShe
成功了!谢谢!是什么原因呢? - MoShe
2
我也更新了我的帖子,原因是这样。 - Jason

6

如果您正在使用64位操作系统,在尝试获取HKEY_LOCAL_MACHINE\SOFTWARE\RSA时,实际上是在查找HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\RSA。这就是为什么您会得到null的原因。


3
如果你能提供一些解决方案,那么答案会更好。如果不能,请将此作为对问题的评论包含在内。 - Prerak Sola
只有当应用程序是32位应用程序时才是真实的,此时64位操作系统将在“HKLM \ SOFTWARE \ Wow6432Node”下重定向读取和写入。如果应用程序是64位应用程序,则64位Windows不会重定向写入。 - Craig Tullis

2
我遇到了完全相同的问题,后来在这个帖子中找到了解决办法。
对我来说,解决方案是:
1. VS2019 > 项目 > 应用程序属性 > 构建 > 常规 > 我的平台目标:"Any CPU" 已经被选中 2. *取消选中--首选32位 只有管理员才需要使用 Registry.SetValue 更新: 今天我学到了另一件事情。
3. 由 Registry.GetValue 赋值的变量必须是静态的。

我曾经遇到过同样的问题,它运行的是32位版本,对于一些注册表的部分,它将无法工作。非常感谢。 - Taki7o7

1

接着Palanikumar的评论(很抱歉我还没获得足够的声望来回复他的帖子!),我在构建选项中取消了“首选32位”,这解决了我的问题。当我读取注册表值(在32位注册表中)时,特定DWORD值总是返回1,即使它被设置为0!让我挠破了头,尝试重新启动,更改密钥等,但没有任何修复方法,直到我取消了这个选项。现在正确地获得了0值!太神奇了!

string keyValue = key.GetValue("ChangeMeToKeyName").ToString();

                    if (keyValue == "0")
                    {
                        //DoThings
                    }

1

这里提供的解决方案都无法解决我的问题,我仍然从注册表读取null。最终,我找到了一种对我有用的解决方案,基于上面答案的综合。感谢所有人指导我正确的方向。

我知道我来晚了,但如果上述解决方案对他们无效,我认为这可能会帮助其他人。

这个函数是类的一部分:

/// <summary>
/// Gets the specified setting name.
/// </summary>
/// <param name="settingName">Name of the setting.</param>
/// <returns>Returns Setting if the read was successful otherwise, "undefined".</returns>
public static string get(string settingName)
{
    RegistryKey key;

    if (Environment.Is64BitOperatingSystem)
        key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\MyCompany\MyProductName", false);
    else
        key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\MyCompany\MyProductName", false);

    try
    {
        String value = (String)key.GetValue(settingName);

        return value;
    }
    catch
    {
        // Null is not returned as in this case, it is a valid value.

        return "undefined";
    }
    finally
    {
        key.Close();
    }
}

1
我在路径开头加了额外的"\",确保它被正确设置。

1

查看使用 regedt32.exe 工具的注册表项的安全权限;检查是否以管理员身份运行并关闭了用户账户控制(UAC)。根据 opensubkey 文档,需要先打开它才能访问任何键;http://msdn.microsoft.com/en-us/library/z9f66s0a.aspx


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接