Microsoft.Win32.Registry's GetValue不使用默认值

本文关键字:GetValue 默认值 Win32 Registry Microsoft | 更新日期: 2023-09-27 18:10:46

我有一个在x64环境(Win7)上运行的遗留(我没有构建它)应用程序。我怀疑它以前是在32位环境下运行的

无论如何,我看到呼叫Registry.GetValue(key, value, default)

默认值似乎被忽略了。

看看这段疯狂的代码:

// Up above the sky, so high
using Microsoft.Win32;
// ...
string location = "HKEY_LOCAL_MACHINE'SOFTWARE'..."; // ...
// ...
string registryValue = (string)Registry.GetValue(location, "Uri", "http://localhost/");
if (string.isNullOrEmpty(registryValue) {
  throw new Exception("What the ... ?!");
}

在一个类似的例子中,异常被严重抛出。(实际上,尽管使用默认值,还是会出现空引用异常)。

我检查了注册表项一直到最后一层;都在我的注册表里。

这对某人有效,但不适合我。

这是一个bug吗?这是怎么回事?

Microsoft.Win32.Registry's GetValue不使用默认值

很可能您被注册表重定向捕获了。在64位系统上运行32位进程。所以HKLM'Software被重定向到HKLM'Software'Wow6432Node

当键不存在时,Registry.GetValue返回null而不是默认值,因此抛出异常。

如果在指定的键中没有找到名称,则返回您提供的默认值,如果指定的键不存在,则返回null。

默认值仅在找到指定的键(即第一个参数,即在您的示例中location) 时返回,但在该键中不存在具有指定名称的值(第二个参数,在您的示例中"Uri")。

如果键本身不存在,则返回null引用。

这在MSDN上有很好的记录。

可能您正在寻找的键不存在,可能是因为您现在运行在64位环境中,这意味着如果您的应用程序是32位进程,则HKLM'Software键将映射到HKLM'Software'Wow6432Node

我知道这是古老的,但万一有人偶然发现这个问题,我发现了一个对我很有效的方法。我使用OpenSubKey,而不是GetValue。

RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software'MyProduct");
string data = key.GetValue("MyValue") as string;

注册表的术语使我有些困惑。它不是简单的键->值存储,它更像是键->值->数据。

我不知道为什么,但我解决了使用

My.Computer.Registry.CurrentUser.GetValue("Software'Mykey","Default Value")
instead of
My.Computer.Registry.GetValue("HKEY_CURRENT_USER'Software","Mykey","Default Value")

如果键不存在,第一个例子返回"默认值",第二个例子返回空对象!