Skip to content
The Road to Delphi — Delphi, VCL, VCL Styles, UxTheme and WinAPI

WMI Delphi Code Creator – New Features

,

Update :  to get last version  check the new page of this project

Many new features was added to the application

The tool allows you compile and run the generated code directly without leaving the application

check the screen to select the installed Delphi compiler to use.

and the compiler result output

Added support for call WMI methods

Check the generated code for the Win32_Process wmi class and the Create method.

[sourcecode language=”delphi” wraplines=”false”]
//——————————————————————————
// This code was generated by the Wmi Delphi Code Creator http://theroadtodelphi.wordpress.com
// Version: 1.0.0.11
//
//
//
// LIABILITY DISCLAIMER
// THIS GENERATED CODE IS DISTRIBUTED "AS IS". NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED.
// YOU USE IT AT YOUR OWN RISK. THE AUTHOR NOT WILL BE LIABLE FOR DATA LOSS,
// DAMAGES AND LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING OR MISUSING THIS CODE.
//
//
//——————————————————————————
program GetWMI_Info;

{$APPTYPE CONSOLE}

uses
SysUtils,
ActiveX,
ComObj,
Variants;

function VarArrayToStr(const vArray: variant): string;

function _VarToStr(const V: variant): string;
var
Vt: integer;
begin
Vt := VarType(V);
case Vt of
varSmallint,
varInteger : Result := IntToStr(integer(V));
varSingle,
varDouble,
varCurrency : Result := FloatToStr(Double(V));
varDate : Result := VarToStr(V);
varOleStr : Result := WideString(V);
varBoolean : Result := VarToStr(V);
varVariant : Result := VarToStr(Variant(V));
varByte : Result := char(byte(V));
varString : Result := String(V);
varArray : Result := VarArrayToStr(Variant(V));
end;
end;

var
i : integer;
begin
Result := ‘[‘;
if (VarType(vArray) and VarArray)=0 then
Result := _VarToStr(vArray)
else
for i := VarArrayLowBound(vArray, 1) to VarArrayHighBound(vArray, 1) do
if i=VarArrayLowBound(vArray, 1) then
Result := Result+_VarToStr(vArray[i])
else
Result := Result+’|’+_VarToStr(vArray[i]);

Result:=Result+’]’;
end;

function VarStrNull(const V:OleVariant):string; //avoid problems with null strings
begin
Result:=”;
if not VarIsNull(V) then
begin
if VarIsArray(V) then
Result:=VarArrayToStr(V)
else
Result:=VarToStr(V);
end;
end;

function GetWMIObject(const objectName: String): IDispatch; //create the Wmi instance
var
chEaten: Integer;
BindCtx: IBindCtx;
Moniker: IMoniker;
begin
OleCheck(CreateBindCtx(0, bindCtx));
OleCheck(MkParseDisplayName(BindCtx, StringToOleStr(objectName), chEaten, Moniker));
OleCheck(Moniker.BindToObject(BindCtx, nil, IDispatch, Result));
end;

//The Create method creates a new process.
//The method returns an integer value
//that can be interpretted as follows:
//0 – Successful completion.
//2 – The user
//does not have access to the requested information.
//3 – The user does not have
//sufficient privilge.
//8 – Unknown failure.
//9 – The path specified does not
//exist.
//21 – The specified parameter is invalid.
//Other – For integer values
//other than those listed above, refer to Win32 error code documentation.

procedure Invoke_Win32_Process_Create;
var
objWMIService : OLEVariant;
objInvoker : OLEVariant;
objInParams : OLEVariant;
objOutParams : OLEVariant;
begin
objWMIService := GetWMIObject(Format(‘winmgmts:\\%s\%s’,[‘.’,’root\CIMV2′]));
objInvoker := objWMIService.Get(‘Win32_Process’);
objInParams := objInvoker.Methods_.Item(‘Create’).InParameters.SpawnInstance_();
objInParams.CommandLine:=’notepad.exe’;
objOutParams := objWMIService.ExecMethod(‘Win32_Process’, ‘Create’, objInParams);
Writeln(‘ProcessId ‘+VarStrNull(objOutParams.ProcessId));
Writeln(‘ReturnValue ‘+VarStrNull(objOutParams.ReturnValue));
end;

begin
try
CoInitialize(nil);
try
Invoke_Win32_Process_Create;
Readln;
finally
CoUninitialize;
end;
except
on E:Exception do
begin
Writeln(E.Classname, ‘:’, E.Message);
Readln;
end;
end;
end.
[/sourcecode]

Added support for WMI events

Check the generated code for the __InstanceCreationEvent Event using as traget instance the Win32_Process class, this sample code check when new process is launched in the whole system.

[sourcecode language=”delphi” wraplines=”false”]
//——————————————————————————
// This code was generated by the Wmi Delphi Code Creator http://theroadtodelphi.wordpress.com
// Version: 1.0.0.11
//
//
//
// LIABILITY DISCLAIMER
// THIS GENERATED CODE IS DISTRIBUTED "AS IS". NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED.
// YOU USE IT AT YOUR OWN RISK. THE AUTHOR NOT WILL BE LIABLE FOR DATA LOSS,
// DAMAGES AND LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING OR MISUSING THIS CODE.
//
//
//——————————————————————————
program GetWMI_Info;

{$APPTYPE CONSOLE}

uses
Windows,
SysUtils,
ActiveX,
ComObj,
Variants;

function VarArrayToStr(const vArray: variant): string;

function _VarToStr(const V: variant): string;
var
Vt: integer;
begin
Vt := VarType(V);
case Vt of
varSmallint,
varInteger : Result := IntToStr(integer(V));
varSingle,
varDouble,
varCurrency : Result := FloatToStr(Double(V));
varDate : Result := VarToStr(V);
varOleStr : Result := WideString(V);
varBoolean : Result := VarToStr(V);
varVariant : Result := VarToStr(Variant(V));
varByte : Result := char(byte(V));
varString : Result := String(V);
varArray : Result := VarArrayToStr(Variant(V));
end;
end;

var
i : integer;
begin
Result := ‘[‘;
if (VarType(vArray) and VarArray)=0 then
Result := _VarToStr(vArray)
else
for i := VarArrayLowBound(vArray, 1) to VarArrayHighBound(vArray, 1) do
if i=VarArrayLowBound(vArray, 1) then
Result := Result+_VarToStr(vArray[i])
else
Result := Result+’|’+_VarToStr(vArray[i]);

Result:=Result+’]’;
end;

function VarStrNull(const V:OleVariant):string; //avoid problems with null strings
begin
Result:=”;
if not VarIsNull(V) then
begin
if VarIsArray(V) then
Result:=VarArrayToStr(V)
else
Result:=VarToStr(V);
end;
end;

function GetWMIObject(const objectName: String): IDispatch; //create the Wmi instance
var
chEaten: Integer;
BindCtx: IBindCtx;
Moniker: IMoniker;
begin
OleCheck(CreateBindCtx(0, bindCtx));
OleCheck(MkParseDisplayName(BindCtx, StringToOleStr(objectName), chEaten, Moniker));
OleCheck(Moniker.BindToObject(BindCtx, nil, IDispatch, Result));
end;

function KeyPressed:boolean; //Detect if an key is pressed
var
NumEvents : DWORD;
ir : _INPUT_RECORD;
bufcount : DWORD;
StdIn : THandle;
begin
Result:=false;
StdIn := GetStdHandle(STD_INPUT_HANDLE);
NumEvents:=0;
GetNumberOfConsoleInputEvents(StdIn,NumEvents);
if NumEvents<> 0 then
begin
PeekConsoleInput(StdIn,ir,1,bufcount);
if bufcount <> 0 then
begin
if ir.EventType = KEY_EVENT then
begin
if ir.Event.KeyEvent.bKeyDown then
result:=true
else
FlushConsoleInputBuffer(StdIn);
end
else
FlushConsoleInputBuffer(StdIn);
end;
end;
end;

Procedure Event___InstanceCreationEvent_Target_Win32_Process;
var
objWMIService : OLEVariant;
objEvent : OLEVariant;
objResult : OLEVariant;
begin
objWMIService := GetWMIObject(‘winmgmts:\\.\root\CIMV2’);
objEvent := objWMIService.ExecNotificationQuery(‘Select * from __InstanceCreationEvent Within 1 Where TargetInstance ISA ”Win32_Process” ‘);
while not KeyPressed do
begin
try
objResult := objEvent.NextEvent(100);
except
on E:EOleException do
if EOleException(E).ErrorCode=HRESULT($80043001) then //Check for the timeout error wbemErrTimedOut 0x80043001
objResult:=Null
else
raise;
end;

if not VarIsNull(objResult) then
begin
Writeln(‘Caption ‘+VarStrNull(objResult.TargetInstance.Caption));
Writeln(‘CommandLine ‘+VarStrNull(objResult.TargetInstance.CommandLine));
Writeln(‘CreationClassName ‘+VarStrNull(objResult.TargetInstance.CreationClassName));
Writeln(‘CreationDate ‘+VarStrNull(objResult.TargetInstance.CreationDate));
Writeln(‘CSCreationClassName ‘+VarStrNull(objResult.TargetInstance.CSCreationClassName));
Writeln(‘CSName ‘+VarStrNull(objResult.TargetInstance.CSName));
Writeln(‘Description ‘+VarStrNull(objResult.TargetInstance.Description));
Writeln(‘ExecutablePath ‘+VarStrNull(objResult.TargetInstance.ExecutablePath));
Writeln(‘ExecutionState ‘+VarStrNull(objResult.TargetInstance.ExecutionState));
Writeln(‘Handle ‘+VarStrNull(objResult.TargetInstance.Handle));
Writeln(‘HandleCount ‘+VarStrNull(objResult.TargetInstance.HandleCount));
Writeln(‘InstallDate ‘+VarStrNull(objResult.TargetInstance.InstallDate));
Writeln(‘KernelModeTime ‘+VarStrNull(objResult.TargetInstance.KernelModeTime));
Writeln(‘MaximumWorkingSetSize ‘+VarStrNull(objResult.TargetInstance.MaximumWorkingSetSize));
Writeln(‘MinimumWorkingSetSize ‘+VarStrNull(objResult.TargetInstance.MinimumWorkingSetSize));
Writeln(‘Name ‘+VarStrNull(objResult.TargetInstance.Name));
Writeln(‘OSCreationClassName ‘+VarStrNull(objResult.TargetInstance.OSCreationClassName));
Writeln(‘OSName ‘+VarStrNull(objResult.TargetInstance.OSName));
Writeln(‘OtherOperationCount ‘+VarStrNull(objResult.TargetInstance.OtherOperationCount));
Writeln(‘OtherTransferCount ‘+VarStrNull(objResult.TargetInstance.OtherTransferCount));
Writeln(‘PageFaults ‘+VarStrNull(objResult.TargetInstance.PageFaults));
Writeln(‘PageFileUsage ‘+VarStrNull(objResult.TargetInstance.PageFileUsage));
Writeln(‘ParentProcessId ‘+VarStrNull(objResult.TargetInstance.ParentProcessId));
Writeln(‘PeakPageFileUsage ‘+VarStrNull(objResult.TargetInstance.PeakPageFileUsage));
Writeln(‘PeakVirtualSize ‘+VarStrNull(objResult.TargetInstance.PeakVirtualSize));
Writeln(‘PeakWorkingSetSize ‘+VarStrNull(objResult.TargetInstance.PeakWorkingSetSize));
Writeln(‘Priority ‘+VarStrNull(objResult.TargetInstance.Priority));
Writeln(‘PrivatePageCount ‘+VarStrNull(objResult.TargetInstance.PrivatePageCount));
Writeln(‘ProcessId ‘+VarStrNull(objResult.TargetInstance.ProcessId));
Writeln(‘QuotaNonPagedPoolUsage ‘+VarStrNull(objResult.TargetInstance.QuotaNonPagedPoolUsage));
Writeln(‘QuotaPagedPoolUsage ‘+VarStrNull(objResult.TargetInstance.QuotaPagedPoolUsage));
Writeln(‘QuotaPeakNonPagedPoolUsage’+VarStrNull(objResult.TargetInstance.QuotaPeakNonPagedPoolUsage));
Writeln(‘QuotaPeakPagedPoolUsage ‘+VarStrNull(objResult.TargetInstance.QuotaPeakPagedPoolUsage));
Writeln(‘ReadOperationCount ‘+VarStrNull(objResult.TargetInstance.ReadOperationCount));
Writeln(‘ReadTransferCount ‘+VarStrNull(objResult.TargetInstance.ReadTransferCount));
Writeln(‘SessionId ‘+VarStrNull(objResult.TargetInstance.SessionId));
Writeln(‘Status ‘+VarStrNull(objResult.TargetInstance.Status));
Writeln(‘TerminationDate ‘+VarStrNull(objResult.TargetInstance.TerminationDate));
Writeln(‘ThreadCount ‘+VarStrNull(objResult.TargetInstance.ThreadCount));
Writeln(‘UserModeTime ‘+VarStrNull(objResult.TargetInstance.UserModeTime));
Writeln(‘VirtualSize ‘+VarStrNull(objResult.TargetInstance.VirtualSize));
Writeln(‘WindowsVersion ‘+VarStrNull(objResult.TargetInstance.WindowsVersion));
Writeln(‘WorkingSetSize ‘+VarStrNull(objResult.TargetInstance.WorkingSetSize));
Writeln(‘WriteOperationCount ‘+VarStrNull(objResult.TargetInstance.WriteOperationCount));
Writeln(‘WriteTransferCount ‘+VarStrNull(objResult.TargetInstance.WriteTransferCount));
Writeln(”);
end;
end;
end;

begin
try
CoInitialize(nil);
try
Event___InstanceCreationEvent_Target_Win32_Process;
Readln;
finally
CoUninitialize;
end;
except
on E:Exception do
begin
Writeln(E.Classname, ‘:’, E.Message);
Readln;
end;
end;
end.
[/sourcecode]

Improved WMi explorer window

this option now shows more info about the wmi classes, including the properties types, methods parameters (in, out)

also includes an option to view the values of the properties of the selected WMI class

and finally a new option called Search WMI Database, this option lets you search in all the wmi classes for a particular word.

see this sample image looking for the Motherboard word

Download The installer from here

And don’t forget , wich all your comments and suggestions are very welcome.

10 responses

  1. Hola Rodrigo.
    Veo que sigues mejorando la aplicación. me alegro. Realmente se va a convertir en algo imprescindible para trabajar con WMI y Delphi.

    Como sugerencias, sino te importa te comentaría que:
    * Sigas manteniendo la versión portable (ZIP con el EXE) si es posible. A muchos de nosotros nos sigue gustando instalar (vía instalador) lo menos posible en Windows.
    * Para las Classes (en la pantalla Principal/Code Generation) estaría bien poder disponer de alguna búsqueda rápida; Por ejemplo, para root/CIMV2 hay más de 900 clases y buscarlas en el desplegable es “poco cómodo”.
    * Tal vez utilizaría un poco más los ToolTips.
    * La posible traducción de la aplicación a varios idiomas también sería una mejora considerable. Es posible que en este caso la gente te ayude, sino siempre estará Google. ;-)

    No quiero hacerme tampoco muy pesado. Felicidades de nuevo por ell programa.

    Un saludo.

    1. Gracias por tus comentarios Neftali, muchas de las sugerencias que tu mencionas ya lo tengo en mente, para incluirlo en nuevas versiones (esta es solo la segunda version), sobre todo el tema de traducir la aplicacion. a lo mejor los amigos del club delphi nos podrian ayudar con eso ;).

  2. This is very well done. This is the kind add-on that should be built into the Delphi IDE. Thank you for your time and contribution!!

    1. Thanks Mick for your comments.

  3. Thank you! Great update in compare to the initial release.

  4. Just one thing; the installer does not as for destination folder, and does not create any icon in Start Menu, so user has to search for the app and find it himself.

    1. Thanks for your comments and suggestions.

  5. Saludos,

    He intentado usar tu generador de código, pero me arroja un error en esta línea al compilar.

    objOutParams := objWMIService.ExecMethod(‘Win32_WindowsProductActivation’, ‘SetProductKey’, objInParams);

    1. Hola Maxium, enviame el codigo completo generado por la aplicacion para revisarlo, incluyendo la clase wmi que usaste , el error que te aparece y la version de delphi que usas.

      mi correo es
      rodrigo dot ruz dot v at gmail dot com

  6. Really nice work!
    Comes in handy :-)

Leave a Reply

Discover more from

Subscribe now to keep reading and get access to the full archive.

Continue reading