使用LIKE 运算符过滤Name/Path 属性时,使用WMI 查询文件系统似乎非常慢,即使过滤器值不包含通配符(% )。
这需要不止一个查询,但您可以获取基本目录的CIM_Directory(实际上是Win32_Directory)实例并自己遍历层次结构...
static void EnumerateDirectory(ManagementObject directory, bool recurse)
{
// Get all related CIM_LogicalFile instances where this is the parent (GroupComponent)
// and the related instance is the child (PartComponent)
using (ManagementObjectCollection children = directory.GetRelated("CIM_LogicalFile", null, null, null, "PartComponent", "GroupComponent", false, null))
foreach (ManagementObject child in children.Cast<ManagementObject>())
switch (child.Path.ClassName)
{
case "CIM_Directory":
case "Win32_Directory":
Console.WriteLine($"Directory: { child["Name"] }");
if (recurse)
EnumerateDirectory(child, true);
break;
case "CIM_DataFile":
Console.WriteLine($" File: { child["Name"] }");
break;
default:
Console.WriteLine($"ERROR: Unexpected { child.Path.ClassName } instance. This should never happen!");
break;
}
}
调用GetRelated() 获取所有CIM_LogicalFile 实例associated with directory; CIM_LogicalFile 是CIM_DataFile 和CIM_Directory 的父类,而CIM_Directory 本身就是Win32_Directory 的父类。我们可以调用更简单的directory.GetRelated("CIM_LogicalFile") 重载,但这会返回一个我们不想要的CIM_Directory 实例:父目录。相反,我们称之为更长的重载,它允许我们指定我们希望 directory 成为 CIM_Directory ⇔ CIM_Directory 关系中的父级。
你会像这样打电话给EnumerateDirectory()...
static void Main()
{
const string directoryPath = @"C:\YC";
ObjectQuery directoryQuery = new SelectQuery(
"CIM_Directory",
$"Name = \"{ directoryPath.Replace(@"\", @"\\") }\""
);
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(directoryQuery))
using (ManagementObjectCollection results = searcher.Get())
using (ManagementObject directory = results.Cast<ManagementObject>().SingleOrDefault())
{
if (directory == null)
Console.WriteLine($"ERROR: The query ' { directoryQuery.QueryString } ' returned no results.");
else
EnumerateDirectory(directory, true);
}
}
如果您只想要目录中的直接子文件,那么代码要简单得多......
static void EnumerateFiles(ManagementObject directory)
{
using (ManagementObjectCollection children = directory.GetRelated("CIM_DataFile"))
foreach (ManagementObject child in children.Cast<ManagementObject>())
Console.WriteLine($"File: { child["Name"] }");
}