Thema: Delphi WMI: Refresh von Daten

Einzelnen Beitrag anzeigen

Profiler

Registriert seit: 30. Dez 2006
14 Beiträge
 
#14

Re: WMI: Refresh von Daten

  Alt 2. Apr 2008, 16:07
Hi,

ich habe mich jetzt schon mehrere Tage damit beschäftigt, aber irgendwie will es nicht richtig funktionieren. Ich habe mir folgende Klasse gebaut:

Delphi-Quellcode:
  TwmiInfo = class(TObject)
  private
    _Select, _From, _Root: String;
    _Instances: TList;
    _wmiRefresher : ISWbemRefresher;
    _wmiRefreshItem : ISWbemRefreshableItem;
    _refreshTime: Cardinal;
    constructor Create(Root, Select, From: String);
    procedure RefresherCreate;
  public
    procedure getInfo;
    procedure refresh;
    function getInstances: TList;
    property refreshTime: Cardinal read _refreshTime;
  end;
...
Delphi-Quellcode:
constructor TwmiInfo.Create(Root, Select, From: String);
begin
  Inherited Create;
  _Root := Root;
  _Select := Select;
  _From := From;
  _Instances := TList.Create;
  RefresherCreate;
end;

procedure TwmiInfo.RefresherCreate;
var
  Locator : ISWbemLocator;
  Services: ISWbemServices;
begin
  _wmiRefresher := CoSWbemRefresher.Create;
  _wmiRefresher.AutoReconnect := True;

  Locator := CoSWbemLocator.Create;
  Services:= Locator.ConnectServer('.', _Root, '', '', '', '', 128, nil); // Wenn OS nicht XP dann 0, sonst 128
  if Services <> nil then
  begin
    _wmiRefreshItem := _wmiRefresher.AddEnum(ISWbemServicesEx(Services), _From, 0, nil);
  end;
end;

function TwmiInfo.getInstances: TList;
begin
  if _Instances.Count = 0 then
    raise NoInstancesFound.Create('getInstances');
  Result := _Instances;
end;

procedure TwmiInfo.getInfo;
var
  wmiLocator: TSWbemLocator;
  wmiServices: ISWbemServices;
  aObjSet : ISWbemObjectSet;
  aNVSDummy : IDispatch;
  Enum, propEnum : IEnumVARIANT;
  vOut : OleVariant;
  dwRetrieved : LongWord;
  wmiProp: SWBemProperty;
  wmiObject: SWBemObject;
  lwValue: LongWord;
  inst: TwmiInstance;
begin
  _Instances.Clear;
  wmiLocator := TSWbemLocator.Create(nil);
  wmiServices := wmiLocator.ConnectServer('.',_Root,'','','','',128, nil);
  aObjSet := wmiServices.ExecQuery('SELECT '+_Select+' FROM '+_From, 'WQL', 0,
    aNVSDummy);
  if aObjSet.Count = 0 then begin
    raise NoInstancesFound.Create('SELECT '+_Select+' FROM '+_From);
    exit;
  end;
  Enum := aObjSet._NewEnum as IEnumVARIANT;
  while Enum.Next(1, vOut, dwRetrieved) = S_OK do begin
    wmiObject := IUnknown(vOut) as SWBemObject;
    inst := TwmiInstance.Create;
    propEnum := (wmiObject.Properties_._NewEnum) as IEnumVariant;
    while (propEnum.Next (1, vOut, lwValue) = S_OK) do begin
      wmiProp := IUnknown(vOut) as SWBemProperty;
      inst.PropName.Add(VarToStr(wmiProp.Name));
      inst.PropValue.Add(VarToStr(wmiProp.Get_Value));
    end;
    _Instances.Add(inst);
  end;
end;

procedure TwmiInfo.refresh;
var
  ObjEnum : IEnumVariant;
  WMITmpObj : OleVariant;
  WmiRefItem : ISWbemRefreshableItem;
  Cnt : Cardinal;
  aObjSet : ISWbemObjectSet;
  Enum, propEnum : IEnumVARIANT;
  vOut : OleVariant;
  dwRetrieved : LongWord;
  wmiProp: SWBemProperty;
  wmiObject: SWBemObject;
  lwValue: LongWord;
  inst: TwmiInstance;
begin
  _wmiRefresher.Refresh(0);
  ObjEnum := (_wmiRefresher._NewEnum) as IEnumVariant;
  while(ObjEnum.Next(1, WMITmpObj, Cnt) = S_OK) do
  begin
    WmiRefItem := IUnknown(WMITmpObj) as ISWbemRefreshableItem;
    if WmiRefItem.IsSet then begin
  _Instances.Clear;
  aObjSet := WmiRefItem.ObjectSet;
  if aObjSet.Count = 0 then begin
    raise NoInstancesFound.Create('SELECT '+_Select+' FROM '+_From);
    exit;
  end;
  Enum := aObjSet.Get__NewEnum as IEnumVARIANT;
  while Enum.Next(1, vOut, dwRetrieved) = S_OK do begin
    wmiObject := IUnknown(vOut) as SWBemObject;
    inst := TwmiInstance.Create;
    propEnum := (wmiObject.Properties_._NewEnum) as IEnumVariant;
    while (propEnum.Next (1, vOut, lwValue) = S_OK) do begin
      wmiProp := IUnknown(vOut) as SWBemProperty;
      inst.PropName.Add(VarToStr(wmiProp.Name));
      inst.PropValue.Add(VarToStr(lwValue));
    end;
    _Instances.Add(inst);
  end;
    end;
  end;
  _refreshTime := GetTickCount;
end;
Der Aufruf erfolgt folgendermaßen:
Delphi-Quellcode:
function getTemperature(Index: Integer = 0): integer;
var
    wmiInfo: TwmiInfo;
    PropIndex: Integer;
begin
  result := 0;
  wmiInfo := TwmiInfo.Create('root\WMI', 'CurrentTemperature', 'MSAcpi_ThermalZoneTemperature');
  wmiInfo.getInfo;
  //[*]
  if Index >= wmiInfo.getInstances.Count then exit;
  PropIndex := TwmiInstance(wmiInfo.getInstances.Items[Index]).PropName.IndexOf('CurrentTemperature');
  Result := StrToInt(TwmiInstance(wmiInfo.getInstances.Items[Index]).PropValue.Strings[PropIndex]);
  Result := (Result div 10)-273;
end;
Soweit funktioniert es auch, wenn ich im Constructor NICHT RefresherCreate aufrufe, nur halt mit nicht aktuellen Werten, aber sobald ich dies tue (egal ob ich dann beim Aufruf noch die Refresh-Funktion aufrufe oder nicht - siehe[*]), fliegt in der Zeile:
    _wmiRefreshItem := _wmiRefresher.AddEnum(ISWbemServicesEx(Services), _From, 0, nil); in RefresherCreate eine EOleException mit dem Hinweis: "Allgemeiner Fehler"

Eine Idee, woran das liegen kann?

Gruß
Profiler
  Mit Zitat antworten Zitat