如何根据我认为的嵌套属性筛选WMI搜索?

时间:2017-05-30 13:53:10

标签: c# wmi

我正在使用以下内容通过WMI获取已加载的依赖项或模块的列表,但是我的搜索字符串问题是正确的,基本上我需要通过其句柄来定位特定的依赖进程,并且handle属性似乎是嵌套在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
        }
    }
}

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

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

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

        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 '。但这可能只是来自上一行,这可能仍然表明查询字符串错误。

1 个答案:

答案 0 :(得分:2)

事实证明,秘诀是references of而非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属性:

\\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对于格式化有点挑剔。 {}内不能有额外的空格。我不知道。

也可以使用associators of。如果您只是获得语法...并且您引用了关联的类型(而不是关联类型)。我的意思是CIM_ProcessExecutables员工CIM_ProcessCIM_DataFile。因此,要仅获取CIM_DataFiles属性...您可以执行此操作:

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

...它可以直接找到CIM_DataFile属性......

\\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来获取属性你想要的:

  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 );
    }
  }

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

  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" ] );
    }
  }

...但不管怎么说都不是超级快,我害怕。