如何根据我认为的嵌套属性过滤 WMI 搜索? [英] How do I filter a WMI search on what I think is a nested property?

查看:27
本文介绍了如何根据我认为的嵌套属性过滤 WMI 搜索?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下内容通过 WMI 获取加载的依赖项或模块的列表,但是在使我的搜索字符串正确时遇到问题,基本上我需要通过其句柄定位特定的依赖进程,并且 handle 属性似乎是嵌套在 ManagementObject 中.

I am using the following to get a list of loaded dependents or modules via WMI, but am having issues geting my search string correct, basically I need to target a specific dependent process via its handle, and the handle property seems to be nested inside a ManagementObject.

var wmiQueryString = string.Format("select * from CIM_ProcessExecutable WHERE Dependent.Handle=\"{0}\"",procID);
using (var searcher = new ManagementObjectSearcher(string.Format(wmiQueryString)))
using (var results = searcher.Get())
{
    foreach (var item in results.Cast<ManagementObject>())
    {
        try
        {
            var dependent = new ManagementObject((string)item["Dependent"]);
            Console.WriteLine(new FileInfo((string)dependent["Name"]).FullName);
        }
        catch (System.Management.ManagementException ex)
        {
            // Process does not exist anymore
        }
    }
}

仅使用Dependent.Handle"似乎不起作用,我尝试过的每个变体都导致无效的查询字符串异常.我假设是因为搜索者不了解对象结构?

Using just "Dependent.Handle" does not seem to work, every variation I have tried has resulted in invalid query string exceptions. I assume because the searcher has no understanding of the object structure?

我可以在 C# 中加载和过滤数据,但出于性能原因,我想在 WMI 查询中进行过滤.

I could load and filter through the data in my C#, but for performance reasons I would like to do the filter in the WMI query.

根据以下答案更新了代码:

        var wmiQueryString = string.Format("ASSOCIATORS OF {{Win32_Process.Handle=\"{0}\" }} WHERE ResultClass = CIM_ProcessExecutable", procID);
        using (var searcher = new ManagementObjectSearcher(wmiQueryString))
        using (var results = searcher.Get())
        {
            foreach (ManagementObject item in results) // This throws System.Management.ManagementException: 'Invalid object path '
            {
                foreach (PropertyData prop in item.Properties) // At this point this is just here for testing, but this is never reached anyway as the exception occurs prior to the iteration.
                {
                    Console.WriteLine("{0}: {1}", prop.Name, prop.Value);
                }

                //var dependent = item["Dependent"] as ManagementObject;
                //Console.WriteLine(new FileInfo((string)dependent["Name"]).FullName);
            }
        }

然而,这会在指示的行上抛出 System.Management.ManagementException: 'Invalid object path '.但这可能只是来自上一行,这可能仍然表明查询字符串错误.

This however throws System.Management.ManagementException: 'Invalid object path ' on the indicated line. But this may just be from the previous line, which may still be indicative of a bad query string.

推荐答案

事实证明,秘诀在于 references of 而不是 associators of.

Turns out, the secret sauce is references of not associators of.

var wmiQueryString = string.Format( "references of {{win32_process.Handle={0}}}", handle );
using ( var searcher = new ManagementObjectSearcher( wmiQueryString ) )
using ( var results = searcher.Get( ) )
{
  foreach ( ManagementObject item in results )
  {
    Console.WriteLine( item.ClassPath ); //--> turns out this is the cim_processexecutalbe

    //--> and these are it's properties...with references to cim_datafile...  
    foreach ( PropertyData prop in item.Properties )
    {
      Console.WriteLine( "{0}: {1}", prop.Name, prop.Value );
    }
  }
}

这将为您提供 CIM_ProcessExecutables 属性:

This gets you the CIM_ProcessExecutables properties:

\\CLAYDEV\root\cimv2:Win32_SessionProcess
Antecedent: \\.\root\cimv2:Win32_LogonSession.LogonId="999"
Dependent: \\.\root\cimv2:Win32_Process.Handle="628"
\\CLAYDEV\root\cimv2:Win32_SystemProcesses
GroupComponent: \\CLAYDEV\root\cimv2:Win32_ComputerSystem.Name="CLAYDEV"
PartComponent: \\CLAYDEV\root\cimv2:Win32_Process.Handle="628"
\\CLAYDEV\root\cimv2:CIM_ProcessExecutable
Antecedent: \\CLAYDEV\root\cimv2:CIM_DataFile.Name="C:\\WINDOWS\\system32\\winlogon.exe"
BaseAddress: 140696226496512
Dependent: \\CLAYDEV\root\cimv2:Win32_Process.Handle="628"
GlobalProcessCount:
ModuleInstance: 1687814144
ProcessCount: 0
....

事实证明 - 正如 Mateo 在评论中指出的那样,references ofassociators of 对格式有点挑剔.{} 内不能有多余的空格.我不知道.

It also turns out - as Mateo points out in the comments, that references of and associators of are kinda finicky about formatting. Can't have extra spaces inside the {}. I didn't know that.

您也可以使用的关联器.如果您只是这样理解语法……并且您指的是 associating 类型(而不是 associating 类型).我的意思是 CIM_ProcessExecutablesCIM_Process 关联到 CIM_DataFile.因此,要仅获取 CIM_DataFiles 属性...您可以这样做:

You can use associators of, too. If you get the syntax just so...and you refer to the associated type (not the associating type). What I mean is CIM_ProcessExecutables associates CIM_Process to CIM_DataFile. So, to get only the CIM_DataFiles properties...you can do this:

  var wmiQueryString = string.Format( "associators of {{win32_process.Handle={0}}} where resultclass=cim_datafile", handle );

...它可以让您直接访问 CIM_DataFile 属性...

...which gets you directly to the CIM_DataFile properties...

\\CLAYDEV\root\cimv2:CIM_DataFile
AccessMask: 17957033
Archive: True
Caption: c:\windows\system32\winlogon.exe
Compressed: False
CompressionMethod:
CreationClassName: CIM_LogicalFile
CreationDate: 20170510121417.106825-240
CSCreationClassName: Win32_ComputerSystem
CSName: CLAYDEV
Description: c:\windows\system32\winlogon.exe
Drive: c:
EightDotThreeFileName: c:\windows\system32\winlogon.exe
Encrypted: False
EncryptionMethod:
Extension: exe
FileName: winlogon
FileSize: 707072
FileType: Application
FSCreationClassName: Win32_FileSystem
FSName: NTFS
Hidden: False
InstallDate: 20170510121417.106825-240
InUseCount:
LastAccessed: 20170510121417.106825-240
LastModified: 20170419020715.554583-240
Manufacturer: Microsoft Corporation
Name: c:\windows\system32\winlogon.exe
Path: \windows\system32\
Readable: True
Status: OK
System: False
Version: 10.0.15063.250
Writeable: True
...

只获取有趣的属性:

我看不出有什么地方可以从 associators ofreferences of 语句中选择子集...但正如下面的评论中所建议的那样,您可以执行 SelectMany 以获取您想要的属性:

I can't see where there's anyway to select a subset from an associators of or references of statement...but as suggested in the comments below, you can do a SelectMany to get just the properties you want:

  var wmiQueryString = string.Format( "associators of {{win32_process.Handle={0}}} where resultclass=cim_datafile", handle );
  using ( var searcher = new ManagementObjectSearcher( wmiQueryString ) )
  {
    var results =
      searcher
      .Get( )
      .OfType<ManagementBaseObject>( )
      .SelectMany
      ( df => df.Properties.OfType<PropertyData>( ).Where( pd => pd.Name == "Caption" ) );

    foreach ( PropertyData item in results )
    {
      Console.WriteLine( item.Value );
    }
  }

问题在于它仍然迭代整个属性集以获取目标属性.直奔你想要的房产似乎跑得更快:

The problem with that is it still iterates the entire property set to get the target property. It seems to run faster to just go straight at the property you want:

  var wmiQueryString = string.Format( "associators of {{win32_process.Handle={0}}} where resultclass=cim_datafile", handle );
  using ( var searcher = new ManagementObjectSearcher( wmiQueryString ) )
  using ( var results = searcher.Get( ) )
  {
    foreach ( ManagementObject item in results )
    {
      Console.WriteLine( item[ "Caption" ] );
    }
  }

...但恐怕这两种方式都不是特别快.

...but it's not super fast either way, I'm afraid.

这篇关于如何根据我认为的嵌套属性过滤 WMI 搜索?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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