1

所以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 根中创建键。

我想不出不属于这些异常情况之一的故障情况。

那么我错过了什么?

4

2 回答 2

3

你需要忽略这一点,它实际上并没有发生。根本问题是注册表的本机 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 写博客 :)

于 2013-11-08T18:19:50.993 回答
0

在参考源中查看,CreateSubKey()只有一个代码路径可能返回 null:当RegCreateKeyEx()返回 0 (ERROR_SUCCESS),但生成的密钥句柄(phkResult输出参数)无效(INVALID_HANDLENULL)时。

该代码路径包含一个断言:

BCLDebug.Assert(false, "Unexpected code path in RegistryKey::CreateSubKey");

所以我想这意味着CreateSubKey()永远不应该返回null。也许 MSDN 文档只是从 复制粘贴OpenSubKey,当密钥丢失时返回 null ?

于 2013-11-08T16:12:34.073 回答