2

该函数以什么顺序RegistryKey.GetSubKeyNames返回子键?它们是按字母顺序排列的吗?还是它们以某种随机顺序对应于它们在注册表中的存储?

我已经进行了多次搜索并检查了 MSDN,但我还没有找到明确的答案。理想情况下,MSDN 会声明键排序后或明确声明它们的顺序是随机的......

我想知道的原因是我想编写代码来检测注册表中 COM 类的所有版本。它们将具有 <base-name>13、<base-name>14 等名称。如果对键进行排序,我可以找到第一个匹配的,遍历所有与我的搜索匹配的,然后短路一旦键不再匹配我的搜索。然后我就不必遍历所有的子键。

4

3 回答 3

5

由于文档不保证任何特定顺序,因此您不能假设任何特定顺序。如果您需要特定的订单,您必须自己排序。(顺序不是随机的,但也不是排序的。)

于 2013-05-06T20:06:59.553 回答
1

我不能说这是一个确定的答案,但是在尝试为自己回答相同的问题时,我得出的结论是,这是存储顺序,即 FIFO 或自然顺序。

我使用的所有注册表编辑器都按字母顺序对键名和值名进行排序。这不是自然顺序。RegScanner 向我展示了我认为 HKLM\Software\Microsoft\Windows\CurrentVersion\Run 的自然顺序。

除了删除键中的所有值然后按字母顺序放回之外,我不知道有任何方法可以使自然顺序与字母顺序匹配。但是,如果稍后添加新值,则此顺序将被破坏,因为该新值将在最后添加。

于 2020-07-22T02:45:40.793 回答
0

我同意如果没有记录,你不能假设某些事情,但很多时候文档可能是错误的、过时的或不存在的。

因此,当使用 JetBrains 的 dotPeek 并查看 mscorlib.dll 时,我们看到以下代码用于拉取 SubKeyNames:

[SecuritySafeCritical]
Public String[] GetSubKeyNames()
{
  this.CheckPermission(RegistryKey.RegistryInternalCheck.CheckKeyReadPermission, (String) null, False, RegistryKeyPermissionCheck.Default);
  Return this.InternalGetSubKeyNames();
}

[SecurityCritical]
internal unsafe String[] InternalGetSubKeyNames()
{
  this.EnsureNotDisposed();
  Int length1 = this.InternalSubKeyCount();
  String[] strArray = New String[length1];
  If (length1 > 0)
  {
    Char[] chArray = New Char[256];
    fixed (Char* lpName = &chArray[0])
    {
      For (Int dwIndex = 0; dwIndex < length1; ++dwIndex)
      {
        Int length2 = chArray.Length;
        Int errorCode = Win32Native.RegEnumKeyEx(this.hkey, dwIndex, lpName, ref length2, (Int[]) null, (StringBuilder) null, (Int[]) null, (Long[]) null);
        If (errorCode != 0)
          this.Win32Error(errorCode, (String) null);
        strArray[dwIndex] = New String(lpName);
      }
    }
  }
  Return strArray;
}

所以 - 订单将始终使用 RegEnumKeyEx 函数。看那里我们看到“因为子键没有排序,任何新的子键都将有一个任意的索引。这意味着该函数可以以任何顺序返回子键。”

https://msdn.microsoft.com/en-us/library/windows/desktop/ms724862(v=vs.85).aspx

这是你的肯定答案。

于 2018-01-03T20:28:24.577 回答