如何根据我认为的嵌套 属性 过滤 WMI 搜索?
How do I filter a WMI search on what I think is a nested property?
我正在使用以下命令通过 WMI 获取加载的依赖项或模块列表,但是在使我的搜索字符串正确时遇到问题,基本上我需要通过它的句柄和句柄来定位特定的依赖进程 属性 似乎嵌套在 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" 似乎不起作用,我尝试过的每个变体都导致无效查询字符串异常。我假设是因为搜索者不了解对象结构?
我可以在我的 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 '
。但这可能只是来自上一行,这可能仍然表示查询字符串错误。
事实证明,秘诀是 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 of
和 associators of
在格式化方面有点挑剔。 {} 中不能有多余的空格。我不知道。
您也可以使用associators of
。如果你得到的语法就是这样......并且你指的是 associated 类型(而不是 associated 类型)。我的意思是 CIM_ProcessExecutables
将 CIM_Process
关联到 CIM_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
...
只获取感兴趣的属性:
我看不出哪里有 select 来自 associators of
或 references 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" ] );
}
}
...但恐怕这两种方式都不是特别快。
我正在使用以下命令通过 WMI 获取加载的依赖项或模块列表,但是在使我的搜索字符串正确时遇到问题,基本上我需要通过它的句柄和句柄来定位特定的依赖进程 属性 似乎嵌套在 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" 似乎不起作用,我尝试过的每个变体都导致无效查询字符串异常。我假设是因为搜索者不了解对象结构?
我可以在我的 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 '
。但这可能只是来自上一行,这可能仍然表示查询字符串错误。
事实证明,秘诀是 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 of
和 associators of
在格式化方面有点挑剔。 {} 中不能有多余的空格。我不知道。
您也可以使用associators of
。如果你得到的语法就是这样......并且你指的是 associated 类型(而不是 associated 类型)。我的意思是 CIM_ProcessExecutables
将 CIM_Process
关联到 CIM_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
...
只获取感兴趣的属性:
我看不出哪里有 select 来自 associators of
或 references 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" ] );
}
}
...但恐怕这两种方式都不是特别快。