如何获取WbemScripting查询返回的列的名称?

时间:2011-03-02 17:08:44

标签: delphi wmi wmi-query enumerate

我有以下程序来运行WMI查询,它运行得非常好。

procedure TFormMain.GetWMIOSInfo(const RemoteMachine, Username, Password: string);
var
  FSWbemLocator: OLEVariant;
  FWMIService: OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject: OLEVariant;
  oEnum: IEnumvariant;
  iValue: LongWord;
begin;
  try
    FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
    FWMIService := FSWbemLocator.ConnectServer(RemoteMachine, 'root\CIMV2', Username, Password);
    FWbemObjectSet := FWMIService.ExecQuery(
        'select screenwidth, screenheight, status from Win32_DesktopMonitor','WQL', 0);
    try
      oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
      while oEnum.Next(1, FWbemObject, iValue) = 0 do
        begin
          Listbox1.Items.Add(
            VarToStr(FWbemObject.availability) + ', ' + 
            VarToStr(FWbemObject.screenwidth)  + ', ' +
            VarToStr(FWbemObject.screenheight));

          FWbemObject := Unassigned;
        end;

    finally
      FWbemObjectSet := Unassigned;
    end;

  Except on E: Exception do
    Raise;
  end;
end;

我想更改查询以返回select * from Win32_DesktopMonitor之类的所有字段。我的问题是我不知道如何确定FWbemObject中查询返回的列的名称。即。我想列举FWbemObject

中的列
Listbox1.Items.Add(
  VarToStr(FWbemObject.<?>) + ', ' + 
  VarToStr(FWbemObject.<?>)  + ', ' +
  ....
  VarToStr(FWbemObject.<?>));

2 个答案:

答案 0 :(得分:3)

Pieter您必须使用SWbemObject.Properties_对象的SWbemObject属性。

检查此样本。

program GetWMI_Info;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  ActiveX,
  ComObj,
  Variants;


procedure  GetWin32_DesktopMonitorInfo;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;

  FProperties   : OLEVariant;
  oEnumProp     : IEnumvariant;
  iValueProp    : LongWord;
  FPropObj      : OLEVariant;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
  FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_DesktopMonitor','WQL',0);
  oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  if oEnum.Next(1, FWbemObject, iValue) = 0 then
  begin

    FProperties   := FWbemObject.Properties_;
    oEnumProp     := IUnknown(FProperties._NewEnum) as IEnumVariant;
    while oEnumProp.Next(1, FPropObj, iValueProp) = 0 do
    begin
       Writeln(FPropObj.Name);
       FPropObj:=Unassigned; //prevent memory leak
    end;

    FWbemObject:=Unassigned;//prevent memory leak
  end;
end;


begin
 try
    CoInitialize(nil);
    try
      GetWin32_DesktopMonitorInfo;
      Readln;
    finally
    CoUninitialize;
    end;
 except
    on E:Exception do
    begin
        Writeln(E.Classname, ':', E.Message);
        Readln;
    end;
  end;
end.

答案 1 :(得分:2)

SWbemObject接口公开了Properties_属性,这是一个集合(因此您可以枚举它,可能与枚举SWebmObjectSet返回的ExecQuery接口的方式相同。 )。此集合的项目是SWbemProperty接口,可显示NameValue属性。