有没有一种使用WMI查询远程文件系统的更快方法? [英] Is there a faster way to query a remote filesystem with WMI?

查看:30
本文介绍了有没有一种使用WMI查询远程文件系统的更快方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试递归地获取目录C:YC下的所有文件--5个或6个文件。我绑定到对远程计算机的一个WMI调用。

我设法使用WQLLIKE运算符执行此调用,但它花费了大约30秒,尽管结果大约是6个文件:

// USING A WQL QUERY
string query = "SELECT Name,LastModified FROM CIM_DataFile WHERE PATH LIKE '\\YC\\%' AND DRIVE ='C:'";
ObjectQuery oQuery = new ObjectQuery();
oQuery.QueryString = query;

ManagementObjectSearcher oSearcher = new ManagementObjectSearcher(scope, oQuery);
oSearcher.Options.Rewindable = false;

// Takes long time
ManagementObjectCollection oReturnCollection = oSearcher.Get();

// SHOWING EACH FILE
foreach (ManagementObject oReturn in oReturnCollection)
{
     Console.WriteLine(oReturn["Name"]?.ToString());
}

是否有更高效的方式使用System.Management对象递归获取文件(使用或不使用WQL,但只需一次WMI调用)?

wmi

在使用LIKE运算符对Name/Path属性进行筛选时,使用推荐答案查询文件系统似乎非常慢,即使筛选值不包含通配符(%)。

这将需要多个查询,但您可以获取基本目录的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 withdirectoryCIM_LogicalFileCIM_DataFileCIM_Directory的父类,而Win32_Directory本身就是Win32_Directory的父类。我们可以调用更简单的directory.GetRelated("CIM_LogicalFile")重载,但这将返回一个我们不想要的CIM_Directory实例:父目录。相反,我们调用较长重载,它允许我们指定希望directory成为CIM_DirectoryCIM_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"] }");
}

这篇关于有没有一种使用WMI查询远程文件系统的更快方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆