如何调用名称存储在字符串中的方法?

时间:2014-01-18 06:23:45

标签: delphi methods wmi delphi-xe2 ole

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;

用法:

ShowMessage(PerformWMISelectQuery('SELECT name FROM Win32_Bios'));

给我:自动化对象

不支持方法'_Field'

如果你改变了

会有用
Result := VarToStr(_colItem._Field);

Result := VarToStr(_colItem.name);

所以,我的问题是,如何在这里使用字符串作为方法名称? 谢谢。

1 个答案:

答案 0 :(得分:4)

要访问SWbemObject对象的属性,您必须使用SWbemObject.Properties_属性

所以改变你的代码

 Result := VarToStr(_colItem._Field);

Result := VarToStr(_colItem.Properties_.item(_Field));