I am experimenting with the use of WMI from within Delphi. Appears quite simple really however I am running into a problem where the amount of memory used by my application keeps growing. In my sample code below the SendPing() function is executed once every second by a TTimer.... each time SendPing is called between 30KB and 100KB is consumed by the application and not released.
Has anyone seen this happen before. Am I doing something wrong in my code??
Any ideas would be great :)
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, ActiveX, WbemScripting_TLB;
type
TForm1 = class(TForm)
Timer1: TTimer;
txtServerName: TLabeledEdit;
txtResponse: TLabeledEdit;
CheckBox1: TCheckBox;
procedure Timer1Timer(Sender: TObject);
procedure CheckBox1Click(Sender: TObject);
private
{ Private declarations }
FPingDNSName: string;
function SendPing: integer;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function TForm1.SendPing: integer;
var // WMI Query Variables
Locator: ISWbemLocator;
Services: ISWbemServices;
SObject: ISWbemObject;
ObjSet: ISWbemObjectSet;
SProp: ISWbemProperty;
Enum: IEnumVariant;
Value: Cardinal;
TempObj: OleVariant;
KN: string;
WMI_PROPERTIES: string;
WMI_CLASS: string;
begin
WMI_PROPERTIES := 'ResponseTime';
WMI_CLASS := 'Win32_PingStatus';
try
//CoInitializeEx(nil, COINIT_APARTMENTTHREADED);
CoInitialize(nil);
Locator := CoSWbemLocator.Create;
Services := Locator.ConnectServer('.', 'root\cimv2', '', '', '','', 0, nil);
ObjSet := Services.ExecQuery('SELECT ' + WMI_PROPERTIES + ' FROM ' + WMI_CLASS + ' WHERE ADDRESS=''' + FPingDNSName + '''', 'WQL', wbemFlagReturnImmediately and wbemFlagForwardOnly , nil);
Enum := (ObjSet._NewEnum) as IEnumVariant;
while (Enum.Next(1, TempObj, Value) = S_OK) do
begin
SObject := IUnknown(tempObj) as ISWBemObject;
KN := 'ResponseTime';
SProp := SObject.Properties_.Item(KN, 0);
if VarIsNull(SProp.Get_Value) then
Result := 99999
else
Result := Integer(SProp.Get_Value);
end;
CoUninitialize;
except // Trap any exceptions
on exception do
begin
Result := 99999;
CoUninitialize;
end;
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
ResponseTime: integer;
begin
Timer1.Enabled := false;
FPingDNSName := Trim(txtServerName.text);
ResponseTime := SendPing;
txtResponse.Text := inttostr(ResponseTime);
Timer1.Enabled := true;
end;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
if CheckBox1.Checked then
Timer1.Enabled := true
else
Timer1.Enabled := false;
end;
end.