C# RegistryKey.GetSubKeyNames中元素的顺序
函数C# RegistryKey.GetSubKeyNames中元素的顺序,c#,.net,C#,.net,函数RegistryKey.GetSubKeyNames返回子键的顺序是什么?它们是按字母顺序排列的吗?或者,它们是否以某种随机顺序对应于它们在注册表中的存储 我已经做了多次搜索并检查了MSDN,但我还没有找到一个明确的答案。理想情况下,MSDN会声明键已排序或显式声明其顺序是随机的 我想知道的原因是我想编写代码来检测注册表中COM类的所有版本。它们会有13、14等名称。如果对键进行排序,我就可以找到第一个匹配的键,迭代所有匹配我的搜索,并在键不再匹配我的搜索时短路。这样我就不必遍历所有的子键。
RegistryKey.GetSubKeyNames
返回子键的顺序是什么?它们是按字母顺序排列的吗?或者,它们是否以某种随机顺序对应于它们在注册表中的存储
我已经做了多次搜索并检查了MSDN,但我还没有找到一个明确的答案。理想情况下,MSDN会声明键已排序或显式声明其顺序是随机的
我想知道的原因是我想编写代码来检测注册表中COM类的所有版本。它们会有13、14等名称。如果对键进行排序,我就可以找到第一个匹配的键,迭代所有匹配我的搜索,并在键不再匹配我的搜索时短路。这样我就不必遍历所有的子键。因为文档不保证任何特定的顺序,所以您不能假设任何特定的顺序。如果您需要特定的订单,您必须自行排序。(顺序不是随机的,但也不是排序的。)我同意,如果没有文档,您不能假设某些东西,但很多时候文档可能是错误的、过时的或不存在的 因此,当JetBrains使用dotPeek并查看mscorlib.dll时,我们看到以下代码用于提取子关键字名称:
[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;
}
[SecuritySafeCritical]
公共字符串[]GetSubKeyNames()
{
this.CheckPermission(RegistryKey.RegistryInternalCheck.CheckKeyReadPermission,(String)null,False,RegistryKeyPermissionCheck.Default);
返回这个.InternalGetSubKeyNames();
}
[证券评论]
内部不安全字符串[]InternalGetSubKeyNames()
{
这是一个;
Int length1=this.InternalSubKeyCount();
字符串[]strArray=新字符串[长度1];
如果(长度1>0)
{
Char[]chArray=新字符[256];
已修复(Char*lpName=&chArray[0])
{
对于(Int-dwIndex=0;dwIndex
因此-订单将始终使用RegEnumKeyEx函数。看看这里,我们看到“因为子键没有顺序,任何新的子键都会有一个任意的索引。这意味着函数可以以任何顺序返回子键。”
这是你的明确答案。我不能说这是一个明确的答案,但当我试图为自己回答同样的问题时,我得出结论,这是存储顺序,即FIFO或自然顺序 我使用过的所有注册表编辑器都按字母顺序对键名和值名进行排序。这不是自然规律。RegScanner向我展示了HKLM\Software\Microsoft\Windows\CurrentVersion\Run的自然顺序
除了删除键中的所有值,然后按字母顺序将它们放回,我不知道有什么方法可以使自然顺序与字母顺序匹配。但是,如果稍后添加新值,则此顺序将被打破,因为新值将在末尾添加。我将把缺少文档解释为“没有定义的顺序”。由于没有明确的文档,我建议假设该顺序是
未定义的。您将返回一个字符串[]
。您可以使用Enumerable.OrderBy()
轻松地对它进行排序,如果它没有得到排序,我只需循环所有键就更有效了。这给了我一个最坏的情况O(n)的性能,而排序首先是O(n^2)或O(n log n),这取决于排序。一般来说,我认为这个答案是正确的。只是我不断发现MSDN上的文档是完全不充分的。这就是我问的原因。:)通常,如果MSDN未指定,则行为未指定。