2011-03-02 75 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

相關問題