就标题和 TL;DR 所要求的内容而言,无法通过以下方式查询方法SELECT
但你可以使用ManagementClass.Methods财产 https://learn.microsoft.com/dotnet/api/system.management.managementclass.methods检查该管理类提供的内容。例如,这段代码...
using (ManagementClass processClass = new ManagementClass("Win32_Process"))
foreach (MethodData method in processClass.Methods)
{
bool isStatic = method.Qualifiers
.Cast<QualifierData>()
.Any(qualifier => string.Equals(qualifier.Name, "Static", StringComparison.OrdinalIgnoreCase));
Console.WriteLine($"{method.Origin}.{method.Name}() [{(isStatic ? "static" : "instance")}]");
if (method.InParameters != null && method.InParameters.Properties.Count > 0)
{
Console.WriteLine("\tInput parameters:");
foreach (PropertyData parameterProperty in method.InParameters.Properties)
Console.WriteLine($"\t\t{parameterProperty.Type} {parameterProperty.Name}");
}
if (method.OutParameters != null && method.OutParameters.Properties.Count > 0)
{
Console.WriteLine("\tOutput parameters:");
foreach (PropertyData parameterProperty in method.OutParameters.Properties)
Console.WriteLine($"\t\t{parameterProperty.Type} {parameterProperty.Name}");
}
}
...产生这个输出...
Win32_Process.Create() [static]
Input parameters:
String CommandLine
String CurrentDirectory
Object ProcessStartupInformation
Output parameters:
UInt32 ProcessId
UInt32 ReturnValue
Win32_Process.Terminate() [instance]
Input parameters:
UInt32 Reason
Output parameters:
UInt32 ReturnValue
Win32_Process.GetOwner() [instance]
Output parameters:
String Domain
UInt32 ReturnValue
String User
...
除非“获取方法”的含义与我认为的不同(不同于calling方法),问题的其余部分似乎完全在处理其他事情,这是填充的必要性Key
调用方法之前的属性。我相信你的另一个问题已经解决了这个问题,为什么 WMI 通过搜索而不是直接工作? https://stackoverflow.com/q/54892478/150605
如果你是什么really询问是“如何确定调用方法所需选择的最小属性集?”,那么您可以通过ManagementClass
, 也。该最小属性集是所有具有Key预选赛 https://learn.microsoft.com/windows/win32/wmisdk/key-qualifier,所以你会使用Properties财产 https://learn.microsoft.com/dotnet/api/system.management.managementbaseobject.properties找到任何财产Qualifiers财产 https://learn.microsoft.com/dotnet/api/system.management.propertydata.qualifiers包含一个限定符Name https://learn.microsoft.com/dotnet/api/system.management.qualifierdata.name of "Key"
.
考虑Win32_Product class https://learn.microsoft.com/previous-versions/windows/desktop/legacy/aa394378(v%3Dvs.85),它代表由 Windows Installer 安装的产品(在我的 Windows 10 系统上确定,与文档不同)these Key
特性...
IdentifyingNumber
Name
Version
假设您想要检索要显示的这些属性...
PackageName
Vendor
Version
...然后致电Uninstall() method https://msdn.microsoft.com/library/aa393941对于具有Name
of "Microsoft .NET Framework 4.8 SDK"
。以下代码显示了尝试此任务的三种不同方法......
- Select 所有属性并调用该方法。
- Select 仅显示您想要显示的属性并调用该方法。
- Select 您要显示的属性加上
Key
特性并调用该方法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
namespace SO49798851
{
static class Program
{
static void Main()
{
// Win32_Product is slow to query, so be patient!
const string className = "Win32_Product";
const string condition = "Name = 'Microsoft .NET Framework 4.8 SDK'";
string[] allProperties = new string[] { "*" };
string[] displayProperties = new string[] { "PackageName", "Vendor", "Version" };
string[] keyProperties = GetKeyPropertyNames(className);
string[] displayPlusKeyProperties = displayProperties.Union(keyProperties).ToArray();
// When run as a non-administrator, the Uninstall() method
// still returns 0 despite not (appearing to) do anything
const string methodName = "Uninstall";
object[] methodArguments = Array.Empty<object>();
Console.WriteLine($"Key properties for class {className}: {string.Join(", ", keyProperties)}");
Console.WriteLine();
FindAndInvoke(className, condition, allProperties, methodName, methodArguments);
FindAndInvoke(className, condition, displayProperties, methodName, methodArguments);
FindAndInvoke(className, condition, displayPlusKeyProperties, methodName, methodArguments);
}
static string[] GetKeyPropertyNames(string className)
{
using (ManagementClass managementClass = new ManagementClass(className))
{
return managementClass.Properties
.Cast<PropertyData>()
.Where(
property => property.Qualifiers
.Cast<QualifierData>()
.Any(qualifier => string.Equals(qualifier.Name, "Key", StringComparison.OrdinalIgnoreCase))
)
.Select(property => property.Name)
.ToArray();
}
}
static void FindAndInvoke(
string className,
string condition,
string[] selectedProperties,
string methodName,
object[] methodArguments
)
{
if (selectedProperties == null)
selectedProperties = Array.Empty<string>();
ObjectQuery query = new SelectQuery(className, condition, selectedProperties);
bool allPropertiesSelected = selectedProperties.Length < 1
|| selectedProperties.Any(propertyName => propertyName == "*");
Console.WriteLine(query.QueryString);
Console.WriteLine(new string('=', query.QueryString.Length));
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
using (ManagementObjectCollection searchResultCollection = searcher.Get())
{
// ManagementObjectCollection doesn't support indexing; this is the
// least-ugly, least-verbose way to enumerate it with an index variable
ManagementObject[] searchResultArray = searchResultCollection.Cast<ManagementObject>().ToArray();
for (int i = 0; i < searchResultArray.Length; i++)
using (ManagementObject searchResult = searchResultArray[i])
{
Console.WriteLine($"{className}[{i}].Path.RelativePath: {searchResult.Path.RelativePath}");
Console.WriteLine($"{className}[{i}].Properties.Count: {searchResult.Properties.Count}");
foreach (PropertyData property in searchResult.Properties)
if (allPropertiesSelected
|| selectedProperties.Contains(property.Name, StringComparer.OrdinalIgnoreCase)
)
{
object displayValue = property.Value ?? "<null>";
Console.WriteLine($"{className}[{i}].Properties[\"{property.Name}\"]: {displayValue}");
}
try
{
object methodResult = searchResult.InvokeMethod(methodName, methodArguments);
Console.WriteLine($"{className}[{i}].{methodName}() completed with result {methodResult}.");
}
catch (Exception ex)
{
Console.WriteLine($"{className}[{i}].{methodName}() failed with {ex}.");
}
Console.WriteLine();
}
}
}
}
}
...并产生这个输出...
Key properties for class Win32_Product: IdentifyingNumber, Name, Version
select * from Win32_Product where Name = 'Microsoft .NET Framework 4.8 SDK'
===========================================================================
Win32_Product[0].Path.RelativePath: Win32_Product.IdentifyingNumber="{949C0535-171C-480F-9CF4-D25C9E60FE88}",Name="Microsoft .NET Framework 4.8 SDK",Version="4.8.03928"
Win32_Product[0].Properties.Count: 27
Win32_Product[0].Properties["AssignmentType"]: 1
Win32_Product[0].Properties["Caption"]: Microsoft .NET Framework 4.8 SDK
Win32_Product[0].Properties["Description"]: Microsoft .NET Framework 4.8 SDK
Win32_Product[0].Properties["HelpLink"]: <null>
Win32_Product[0].Properties["HelpTelephone"]: <null>
Win32_Product[0].Properties["IdentifyingNumber"]: {949C0535-171C-480F-9CF4-D25C9E60FE88}
Win32_Product[0].Properties["InstallDate"]: 20191001
Win32_Product[0].Properties["InstallDate2"]: <null>
Win32_Product[0].Properties["InstallLocation"]: <null>
Win32_Product[0].Properties["InstallSource"]: C:\ProgramData\Microsoft\VisualStudio\Packages\Microsoft.Net.4.8.SDK,version=4.8.3928.1\
Win32_Product[0].Properties["InstallState"]: 5
Win32_Product[0].Properties["Language"]: 1033
Win32_Product[0].Properties["LocalPackage"]: C:\WINDOWS\Installer\34d24bd7.msi
Win32_Product[0].Properties["Name"]: Microsoft .NET Framework 4.8 SDK
Win32_Product[0].Properties["PackageCache"]: C:\WINDOWS\Installer\34d24bd7.msi
Win32_Product[0].Properties["PackageCode"]: {CC6C9CC4-DDCD-4C14-81E1-4007EE49D7C0}
Win32_Product[0].Properties["PackageName"]: sdk_tools48.msi
Win32_Product[0].Properties["ProductID"]: <null>
Win32_Product[0].Properties["RegCompany"]: <null>
Win32_Product[0].Properties["RegOwner"]: <null>
Win32_Product[0].Properties["SKUNumber"]: <null>
Win32_Product[0].Properties["Transforms"]: <null>
Win32_Product[0].Properties["URLInfoAbout"]: <null>
Win32_Product[0].Properties["URLUpdateInfo"]: <null>
Win32_Product[0].Properties["Vendor"]: Microsoft Corporation
Win32_Product[0].Properties["Version"]: 4.8.03928
Win32_Product[0].Properties["WordCount"]: 0
Win32_Product[0].Uninstall() completed with result 0.
select PackageName,Vendor,Version from Win32_Product where Name = 'Microsoft .NET Framework 4.8 SDK'
====================================================================================================
Win32_Product[0].Path.RelativePath:
Win32_Product[0].Properties.Count: 3
Win32_Product[0].Properties["PackageName"]: sdk_tools48.msi
Win32_Product[0].Properties["Vendor"]: Microsoft Corporation
Win32_Product[0].Properties["Version"]: 4.8.03928
Win32_Product[0].Uninstall() failed with System.InvalidOperationException: Operation is not valid due to the current state of the object.
at System.Management.ManagementObject.InvokeMethod(String methodName, Object[] args)
at SO49798851.Program.FindAndInvoke(String className, String condition, String[] selectedProperties, String methodName, Object[] methodArguments) in ...\Program.cs:line 90.
select PackageName,Vendor,Version,IdentifyingNumber,Name from Win32_Product where Name = 'Microsoft .NET Framework 4.8 SDK'
===========================================================================================================================
Win32_Product[0].Path.RelativePath: Win32_Product.IdentifyingNumber="{949C0535-171C-480F-9CF4-D25C9E60FE88}",Name="Microsoft .NET Framework 4.8 SDK",Version="4.8.03928"
Win32_Product[0].Properties.Count: 5
Win32_Product[0].Properties["IdentifyingNumber"]: {949C0535-171C-480F-9CF4-D25C9E60FE88}
Win32_Product[0].Properties["Name"]: Microsoft .NET Framework 4.8 SDK
Win32_Product[0].Properties["PackageName"]: sdk_tools48.msi
Win32_Product[0].Properties["Vendor"]: Microsoft Corporation
Win32_Product[0].Properties["Version"]: 4.8.03928
Win32_Product[0].Uninstall() completed with result 0.
以下是这三个尝试的要点......
- 当然,选择所有属性会导致方法调用成功,但我们最终得到的属性比我们想要的要多得多。
- Selecting exactly the properties we want - but not all
Key
properties - results in a failed method invocation.
- 请注意,即使其中之一
Key
特性,Version
,是我们查询的一部分,searchResult.Path财产 https://learn.microsoft.com/dotnet/api/system.management.managementobject.path在本例中为空,这明确表明我们的结果对象有些问题。
- Selecting exactly the properties we want plus the
Key
properties results in a successful method invocation with no extraneous properties.
- 如果我们有我们想要的属性集合(即
displayProperties
)和一个集合Key
属性(即keyProperties
), the Union()LINQ方法 https://learn.microsoft.com/dotnet/api/system.linq.enumerable.union可以轻松地将它们组合起来以获得最少的属性选择。