2011-03-02 44 views
1

我有以下过程来运行WMI查询,并且它工作得非常好。如何获取WbemScripting查询返回的列的名称?

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.<?>)); 

回答

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. 
+0

有关所列属性的含义,请查看[Win32_DesktopMonitor](http://msdn.microsoft.com/zh-cn/library/aa394122.aspx)官方文档。 – jachguate 2011-03-02 17:35:40

+0

这是“未分配的”语句是否真的有必要?我认为OleVariant会在函数结束时自动完成。 – 2011-03-02 17:56:41

+1

Rob,在这种情况下,因为代码是'if oEnum.Next(1,FWbemObject,iValue)= 0 then',但是如果你使用类似'while oEnum.Next(1,FWbemObject,iValue)= 0'需要设置为'Unassigned'来避免循环内存泄漏。 – RRUZ 2011-03-02 18:01:32

2

SWbemObject接口暴露Properties_属性,它是一个集合(所以你也许可以列举它以同样的方式为您列举由ExecQuery返回SWebmObjectSet接口)。这个集合的项目是SWbemProperty接口,它揭示了NameValue属性。

+0

谢谢您另外指出暴露(名称,值)属性。 – 2011-03-03 09:10:29

相关问题