【问题标题】:Under what circumstances will RegistryKey.CreateSubKey(String) return null?RegistryKey.CreateSubKey(String) 什么情况下会返回null?
【发布时间】:2013-11-08 01:13:25
【问题描述】:
所以RegistryKey.CreateSubKey(String) http://msdn.microsoft.com/en-us/library/ad51f2dx(v=vs.110).aspx 的文档说
返回值:新创建的子键,如果操作失败,则返回 null。如果为子键指定零长度字符串,则返回当前的 RegistryKey 对象。
但是查看异常列表
- ArgumentNullException:当子键为空时。
- SecurityException:当用户没有创建或打开注册表项所需的权限时。
- ObjectDisposedException:当调用此方法的 RegistryKey 关闭时(无法访问已关闭的键)。
- UnauthorizedAccessException:无法写入 RegistryKey 时;例如,它没有作为可写密钥打开,或者用户没有必要的访问权限。
- IOException:当嵌套级别超过 510 时。-或- 发生系统错误,例如删除键,或尝试在 LocalMachine 根目录中创建键。
我想不出不属于这些异常情况之一的故障条件。
那么我错过了什么?
【问题讨论】:
标签:
.net
exception-handling
registry
【解决方案1】:
你需要忽略这一点,它实际上并没有发生。根本问题是注册表的本机 winapi 函数非常不寻常。并且实际上不保证返回的句柄不为空。用 C# 术语来说,“普通”的 winapi 函数是这样使用的:
HANDLE handle = CreateWidget(...);
if (handle == NULL) {
int err = GetLastError();
DealWithError(err);
}
但是注册表功能是这样工作的:
HANDLE handle;
int err = RegCreateKeyEx(..., out handle);
if (err != 0) DealWithError(err);
您可能会看到不同之处,在正常情况下,如果函数失败,则很难保证句柄不会为空。但是注册表函数允许返回空句柄但仍然返回0错误代码的漏洞。 MSDN 文档不能排除这种可能性,因为 winapi 文档没有排除它。
实际上,这种情况永远不会发生,总是会产生错误代码。
不确定这种设计怪癖背后的原始原因可能是什么。我们需要 Raymond Chen 写博客 :)
【解决方案2】:
查看参考源中的CreateSubKey(),只有一个代码路径可能返回null:
当RegCreateKeyEx() 返回 0 (ERROR_SUCCESS),但生成的密钥句柄(phkResult 输出参数)无效(INVALID_HANDLE 或 NULL)时。
该代码路径包含一个断言:
BCLDebug.Assert(false, "Unexpected code path in RegistryKey::CreateSubKey");
所以我猜这意味着CreateSubKey() 永远不应该返回null。
也许 MSDN 文档只是从 OpenSubKey 复制粘贴的,当密钥丢失时返回 null?