uses Windows, System.SysUtils, Dialogs, ActiveX, ComObj, Variants, WinSvc;
function PerformWMISelectQuery(ASelectQuery: string): string;
var
_objWMIService: OLEVariant;
_colItems: OLEVariant;
_colItem: OLEVariant;
_oEnum: IEnumvariant;
_iValue: Longword;
_Field: string;
function GetWMIObject(const objectName: string): IDispatch;
var
_chEaten: Integer;
_BindCtx: IBindCtx;
_Moniker: IMoniker;
begin
try
OleCheck(CreateBindCtx(0, _BindCtx));
OleCheck(MkParseDisplayName(_BindCtx, StringToOleStr(objectName),
_chEaten, _Moniker));
OleCheck(_Moniker.BindToObject(_BindCtx, nil, IDispatch, Result));
except
on E: Exception do
MessageDlg(E.Message, TMsgDlgType.mtError, [TMsgDlgBtn.mbOK], 0);
end;
end;
begin
Result := '';
{ check if service is running }
begin
try
if (Copy(UpperCase(ASelectQuery), 0, 6) <> 'SELECT') or
(Pos('FROM', UpperCase(ASelectQuery)) = 0) or
(Pos(',', ASelectQuery) <> 0) then
raise Exception.Create('Illegal query: ' + ASelectQuery)
else
begin
// get field name
_Field := Copy(ASelectQuery, 8,
Pos(' ', Copy(ASelectQuery, 8, (Length(ASelectQuery)))) - 1);
_objWMIService := GetWMIObject('winmgmts:\\localhost\root\cimv2');
_colItems := _objWMIService.ExecQuery(ASelectQuery, 'WQL', 0);
_oEnum := IUnknown(_colItems._NewEnum) as IEnumvariant;
if _oEnum.Next(1, _colItem, _iValue) = 0 then
begin
Result := VarToStr(_colItem._Field); // Error here
end;
end;
except
on E: Exception do
MessageDlg(E.Message, TMsgDlgType.mtError, [TMsgDlgBtn.mbOK], 0);
end;
end;
end;
Usage:
ShowMessage(PerformWMISelectQuery('SELECT name FROM Win32_Bios'));
Gives me: Method '_Field' not supported by automation object
It would work if you changed
Result := VarToStr(_colItem._Field);
to
Result := VarToStr(_colItem.name);
So, my question is, how to use string as method name here? Thank you.
To access the properties of The SWbemObject object you must use the SWbemObject.Properties_ property
So change your code from
Result := VarToStr(_colItem._Field);
To
Result := VarToStr(_colItem.Properties_.item(_Field));