Question

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.

Was it helpful?

Solution

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));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top