Thema: Delphi WMI: Refresh von Daten

Einzelnen Beitrag anzeigen

Alter Mann

Registriert seit: 15. Nov 2003
Ort: Berlin
934 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#11

Re: WMI: Refresh von Daten

  Alt 30. Mär 2008, 19:02
Hi

Zitat:
ich möchte gern die Temperatur des Prozessors per WMI bekommen, was auch bereits funktioniert...
Nach dem Spruch bin ich davon ausgegangen das er es kann.

Was das Beispiel allerdings bewirken soll ist mir ein wenig unklar.
Gesetzt den Fall, das bereits eine WMI-Abfrage vorhanden ist, dann braucht
sie doch nur in periodischen Abständen wiederholt werden und die Werte sind aktuell.
Etwas anderes passiert im Beispiel auch nicht, die Aktualisierung erfolgt
durch erneuten Aufruf der Methode Refresh.

Zur Umsetzung:

Man nehme eine neue Anwendung, lege 3 Buttons, 2 Labels und eine Checkbox drauf.
Die Anordnung ist frei, es sollte auf die Länge der Texte geachtet werden.


Delphi-Quellcode:
  TMainForm = class(TForm)
    btnRefresh : TButton;
    btnRefresherCreate: TButton;
    btnRemove : TButton;
    lbCount : TLabel;
    lbInfo : TLabel;
    cbAutoReconnect : TCheckBox;
    procedure btnRefreshClick(Sender: TObject);
    procedure btnRefresherCreateClick(Sender: TObject);
    procedure btnRemoveClick(Sender: TObject);
  private
    { Private-Deklarationen }
    WmiRefresher : ISWbemRefresher;
    WmiRefreshItem : ISWbemRefreshableItem;
  public
    { Public-Deklarationen }
  end;
1. Zuerst erstellen wir uns ein Refresher-Objekt und weisen der Eigenschaft AutoReconnect einen entsprechenden
Wert zu, je nachdem ob die Verbindung zum WMI automatisch neu aufgebaut werden soll oder nicht.
2. Da die Funktion ISWbemRefresher.AddEnum einen gültigen Services benötigt, müssen wir uns denn nun besorgen.
3. Ist dies erfolgreich verlaufen, können wir nun über AddEnum den Services und die gewünschte Klasse übergeben.
Zurück bekommen wir ein Interface-Objekt vom Type ISWbemRefreshableItem. Dies benötigen wir, um es bei
bedarf auch wieder entfernen zu können.
4. Gleichzeitig wird die Anzahl der Einträge ausgegeben.

Delphi-Quellcode:
procedure TMainForm.btnRefresherCreateClick(Sender: TObject);
var
  Locator : ISWbemLocator;
  Services: ISWbemServices;
begin
  WmiRefresher := CoSWbemRefresher.Create; // 1.
  WmiRefresher.AutoReconnect := cbAutoReconnect.Checked;

  Locator := CoSWbemLocator.Create; // 2.
  Services:= Locator.ConnectServer('.', '', '', 'root\cimv2', '', '', 128, nil); // Wenn OS nicht XP dann 0, sonst 128
  if Services <> nil then
  begin
    WmiRefreshItem := WmiRefresher.AddEnum(ISWbemServicesEx(Services), 'Win32_Process', 0, nil); // 3.
    lbCount.Caption := 'refreshable Items: ' + IntToStr(WmiRefresher.Count); // 4.
  end;
end;
1. Nachdem der Refresher mittels der Methode Refresh die Werte aktualisiert hat erfolgt der
2. Abruf der Werte über eine Enumeration.
3. Anschließend erfolgt die Ausgabe selbiger.
Delphi-Quellcode:
procedure TMainForm.btnRefreshClick(Sender: TObject);
var
  ObjEnum : IEnumVariant;
  WMITmpObj : OleVariant;
  WmiRefItem : ISWbemRefreshableItem;
  Cnt : Cardinal;
begin
  WmiRefresher.Refresh(0); // 1.
  ObjEnum := (WmiRefresher._NewEnum) as IEnumVariant; // 2.
  while(ObjEnum.Next(1, WMITmpObj, Cnt) = S_OK) do
  begin
    WmiRefItem := IUnknown(WMITmpObj) as ISWbemRefreshableItem;
    if WmiRefItem.IsSet then
     lbInfo.Caption := 'Item with index ' + IntToStr(WmiRefItem.Index) + // 3.
                       ' is an enumerator containing ' +
                       IntToStr(WmiRefItem.ObjectSet.Count) +
                       ' proccess.'
     else
     lbInfo.Caption := 'Item with index ' + IntToStr(WmiRefItem.Index) +
                       ' is a single object';
  end;
end;
Da wir das ISWbemRefreshableItem zwischen gespeichert haben können wir dies mittels Remove
wieder vom Refresher gezielt entfernen, bzw. mittels DeleteAll alle entfernen.

Delphi-Quellcode:
procedure TMainForm.btnRemoveClick(Sender: TObject);
begin
  WmiRefresher.Remove(WmiRefreshItem.Index, 0);
end;
Das war es.

Es wird im diesen Beispiel die Anzeige der laufenden Prozesse angezeigt,
so das leicht die Funktionsfähigkeit überprüft werden kann.

Hier noch einmal alles zusammen:

Delphi-Quellcode:
unit frmMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, WbemScript, StdCtrls;

type
  TMainForm = class(TForm)
    btnRefresh: TButton;
    btnRefresherCreate: TButton;
    cbAutoReconnect: TCheckBox;
    lbCount: TLabel;
    lbInfo: TLabel;
    btnRemove: TButton;
    procedure btnRefreshClick(Sender: TObject);
    procedure btnRefresherCreateClick(Sender: TObject);
    procedure btnRemoveClick(Sender: TObject);
  private
    { Private-Deklarationen }
    WmiRefresher : ISWbemRefresher;
    WmiRefreshItem : ISWbemRefreshableItem;
  public
    { Public-Deklarationen }
  end;

var
  MainForm: TMainForm;

implementation

{$R *.dfm}

uses ActiveX;

procedure TMainForm.btnRefreshClick(Sender: TObject);
var
  ObjEnum : IEnumVariant;
  WMITmpObj : OleVariant;
  WmiRefItem : ISWbemRefreshableItem;
  Cnt : Cardinal;
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
     lbInfo.Caption := 'Item with index ' + IntToStr(WmiRefItem.Index) +
                       ' is an enumerator containing ' +
                       IntToStr(WmiRefItem.ObjectSet.Count) +
                       ' proccess.'
     else
     lbInfo.Caption := 'Item with index ' + IntToStr(WmiRefItem.Index) +
                       ' is a single object';
  end;
end;

procedure TMainForm.btnRefresherCreateClick(Sender: TObject);
var
  Locator : ISWbemLocator;
  Services: ISWbemServices;
begin
  WmiRefresher := CoSWbemRefresher.Create;
  WmiRefresher.AutoReconnect := cbAutoReconnect.Checked;

  Locator := CoSWbemLocator.Create;
  Services:= Locator.ConnectServer('.', '', '', 'root\cimv2', '', '', 128, nil); // Wenn OS nicht XP dann 0, sonst 128
  if Services <> nil then
  begin
    WmiRefreshItem := WmiRefresher.AddEnum(ISWbemServicesEx(Services), 'Win32_Process', 0, nil);
    lbCount.Caption := 'refreshable Items: ' + IntToStr(WmiRefresher.Count);
  end;
end;

procedure TMainForm.btnRemoveClick(Sender: TObject);
begin
  WmiRefresher.Remove(WmiRefreshItem.Index, 0);
end;

end.
Entwickelt mit Delphi 7.

Gruß
  Mit Zitat antworten Zitat