Iterating over SWbemPropertySet objects
com, wmi
Solution
First, the `ItemIndex` property only exist in some versions of the `Microsoft WMI Scripting Library` you can find more info about this topic on this article which I wrote some time ago ` Be careful when you import the Microsoft WMI Scripting Library` (The code uses Delphi but the same applies to any language using this Library).
Now to iterate over the elements of an `SWbemPropertySet` you must get a instance to the enumerator accessing the `_NewEnum` property which provides a method for enumerating a collection of variants using the `IEnumVARIANT` interface. This is done automagically by vbscript, but in others languages like Delphi or C++ must be done manually.
Try this Delphi sample
{$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.
I hope which you can translate this sample to the Go language.
Problem
A WQL query in WMI using the COM API returns a SWbemObjectSet. From this, we can use the ItemIndex method to iterate over all objects in the set, resulting in many SWbemObjects. These have a `Properties_` property, which returns a SWbemPropertySet. This object has a `Count` property, but no `ItemIndex` method, instead only an `Item` method, which takes a string name of the property to fetch. I'd like to iterate over all available properties, thus I don't have the name available. I've tried calling an `ItemIndex` method, but (as per the documentation) it does not exist on this object. There are many VBScript documents around that do something like `For Each prop in object.Properties_`, so I assume this is somehow possible. How can I find all properties?