RegistryKey.CreateSubKey(String)在什么情况下会返回null?

时间:2013-11-08 01:13:25

标签: .net exception-handling registry

所以RegistryKey.CreateSubKey(String) http://msdn.microsoft.com/en-us/library/ad51f2dx(v=vs.110).aspx的doco说

  

返回值:新创建的子键,如果操作失败,则返回null。如果为子键指定了零长度字符串,则返回当前的RegistryKey对象。

然而,查看例外列表

  • ArgumentNullException:当子键为null时。
  • SecurityException:当用户没有创建或打开注册表项所需的权限时。
  • ObjectDisposedException:当关闭调用此方法的RegistryKey时(无法访问关闭的密钥)。
  • UnauthorizedAccessException:无法写入RegistryKey;例如,它没有作为可写密钥打开,或者用户没有必要的访问权限。
  • IOException:当嵌套级别超过510时。 - 或 - 发生系统错误,例如删除密钥或尝试在LocalMachine根目录中创建密钥。

我无法想到一个不会陷入其中一个例外情况的失败情况。

那么我错过了什么?

2 个答案:

答案 0 :(得分:3)

你需要忽略这一点,它实际上并没有发生。根本问题是注册表的本机winapi函数非常不寻常。实际上并不保证返回的句柄不为null。将它放在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来博客:)

答案 1 :(得分:0)

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

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

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

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

相关问题