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ß