迭代SWbemPropertySet对象

mji*_*son 4 com wmi

WMI中的WQL查询使用COM API返回SWbemObjectSet.从这里,我们可以使用ItemIndex方法迭代集合中的所有对象,从而产生许多SWbemObject.它们有一个Properties_属性,它返回一个SWbemPropertySet.

这个对象有一个Count属性,但没有ItemIndex方法,而只有一个Item方法,它取一个属性的字符串名来获取.我想迭代所有可用的属性,因此我没有可用的名称.我试过调用一个ItemIndex方法,但是(根据文档)它不存在于这个对象上.有许多VBScript文档可以做类似的事情For Each prop in object.Properties_,所以我认为这在某种程度上是可行的.

我怎样才能找到所有属性?

RRU*_*RUZ 7

首先,该ItemIndex属性仅存在于某些版本中, Microsoft WMI Scripting Library您可以在本文中找到更多关于此主题的信息,这是我之前写的 Be careful when you import the Microsoft WMI Scripting Library(该代码使用Delphi,但同样适用于使用此库的任何语言).

现在要遍历一个元素,SWbemPropertySet你必须得到一个访问_NewEnum属性的枚举器的实例,它提供了一个使用该IEnumVARIANT接口枚举变量集合的方法.这是由vbscript 自动完成的,但在其他语言中,如Delphi或C++必须手动完成.

试试这个Delphi样本

{$APPTYPE CONSOLE}    

uses
  SysUtils,
  ActiveX,
  ComObj,
  Variants,
  WbemScripting_TLB in 'WbemScripting_TLB.pas';

procedure ShowProperties(const WMINameSpace, WMIClass : string);
var
  WMIServices     : ISWbemServices;
  SWbemObjectSet  : ISWbemObjectSet;
  SObject         : ISWbemObject;
  LProperty       : ISWbemProperty;
  Enum, Enum2     : IEnumVariant;
  TempObj, TempObj2: OleVariant;
  Value           : Cardinal;
  SWbemPropertySet: ISWbemPropertySet;
begin
  WMIServices := CoSWbemLocator.Create.ConnectServer('.', WMINameSpace,'', '', '', '', 0, nil);
  SWbemObjectSet := WMIServices.ExecQuery(Format('Select * FROM %s',[WMIClass]), 'WQL', 0, nil);
  Enum := (SWbemObjectSet._NewEnum) as IEnumVariant;
  if (Enum.Next(1, TempObj, Value) = S_OK) then
  begin
    SObject     := IUnknown(TempObj) as ISWBemObject;
    SWbemPropertySet := SObject.Properties_;
    Enum2 := (SWbemPropertySet._NewEnum) as IEnumVariant;
    while (Enum2.Next(1, TempObj2, Value) = S_OK) do
    begin
      LProperty     := IUnknown(TempObj2) as ISWbemProperty;
      Writeln(LProperty.Name);
      TempObj2:=Unassigned;
    end;
    TempObj:=Unassigned;
  end;
end;

begin
 try
    CoInitialize(nil);
    try
      ShowProperties('root\cimv2','Win32_BaseBoard');
    finally
      CoUninitialize;
    end;
 except
    on E:EOleException do
        Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;
end.
Run Code Online (Sandbox Code Playgroud)

我希望你可以将这个样本翻译成Go语言.