1

我有以下过程来运行 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。IE。我想列举FWbemObject.

Listbox1.Items.Add(
  VarToStr(FWbemObject.<?>) + ', ' + 
  VarToStr(FWbemObject.<?>)  + ', ' +
  ....
  VarToStr(FWbemObject.<?>));
4

2 回答 2

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.
于 2011-03-02T17:31:18.637 回答
2

SWbemObject接口公开了Properties_作为一个集合的属性(因此您可以像枚举由SWebmObjectSet返回的接口一样枚举它ExecQuery)。该集合的项目是SWbemProperty接口,它公开NameValue属性。

于 2011-03-02T17:29:23.750 回答