Accéder à WMI sous Delphi
SOMMAIRE
I Introduction
II Accéder à WMI avec Delphi
IIII Effectuer une requête WMI
IV Conclusion
I Introduction
Nous allons voir dans ce tutoriel comment accéder à WMI à partir de Delphi. Vous pourrez donc utiliser des requêtes pour obtenir des informations concernant des périphériques sur votre réseau y compris les imprimantes. Nous allons détailler en détails la procédure à suivre et nous allons prendre un exemple simple : lister les imprimantes installer sur votre ordinateur. A la fin de ce tutoriel vous serez en mesure d’utiliser WMI dans vos futurs projets pour obtenir d’autres types d’informations.
II Accéder à WMI avec Delphi
La procédure est quelque peu différente par rapport à celle utilisée pour les langages de la plateforme .Net. En effet avec Delphi il n’est pas question de créer des instances d’objets préconçus comme ManagementScope,
Uses …, ComObj, ActiveX, … ;
Pour créer notre objet WMI, nous avons besoin de créer une méthode qui nous permet de réaliser cette opération en utilisant principalement la fonction OleCheck de la bibliothèque importée précédemment.
Nous allons nommer cette fonction GetWMIObject.
Dans un premier temps nous allons créer les variables locales nécessaires :
var chEaten : Integer;
BindCtx : IBindCtx;
Moniker : IMoniker;
OleCheck permet d’accéder et d’envelopper diverses routines COM. Nous allons l’utiliser conjointement avec des fonctions de la bibliothèque ActiveX. Nous allons utiliser dans un premier temps la méthode CreateBindCtx qui va nous retourner un pointeur vers une implémentation de IBindCtx qui est un objet de contexte de liaison. Nous utilisons ensuite la méthode MkParseDisplayName qui convertit la chaine de caractère qu’on lui envoie en argument en un objet système. Nous lui envoyons la chaîne suivante en argument : ‘winmgmts:\\.\root\CIMV2’. Celle-ci nous renvoie un pointeur vers un objet de type Moniker. Nous appelons pour finir la méthode BindToObject de l’objet Moniker. Celle-ci nous permet d’effectuer la liaison avec l’objet demandé. Ensuite elle s’assure du déclenchement de l’opération c’est-à-dire de l’exécution de l’objet si nécessaire, mais surtout elle nous fournit une interface de type IDispatch sur l’objet.
Voici le corps complet de cette fonction :
function GetWMIObject(const ObjectName : String) :IDispatch;
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;
III Effectuer une requête WMI
Maintenant que nous avons créé notre fonction d’accès à notre objet nous pouvons créer une requête nous permettant de lister les imprimantes installées sur un ordinateur.
Nous allons, pour ce faire, créer une nouvelle fonction qui va nous permettre de réaliser une requête et d’exploiter le résultat retourné…
Donc dans un premier temps nous allons définir des variables locales :
var objWMIService : OleVariant;
colItems : OleVariant;
colItem : OleVariant;
oEnum : IEnumVARIANT;
iValue : LongWord;
La variable objWMIService nous permet de créer une instance d’objet à partir de la fonction que l’on a créé précédemment. Les variables colItems, et colItem sont utilisées pour exploiter les résultats de la requête. Nous envoyons en argument de la fonction execQuery de l’objet objWMIService la requête à effectuer, qui est dans notre cas : 'SELECT * FROM win32_printer'. La fonction nous renvoie une liste d’éléments qui nous permet d’initialiser notre objet collection colItems. Il nous faut ensuite balayer cette liste d’éléments. colItems et colItem étant de type OleVariant. Nous devons faire un cast de type. Pour énumérer des valeurs contenues dans un objet de type OleVariant, nous devons le convertir en objet IEnumVariant. Ceci est réalisé par la ligne de code suivante :
oEnum := IUnknown(colItems._NewEnum) as IEnumVariant;
Ensuite on peut énumérer chaque enregistrement de ce résultat par l’intermédiaire d’une boucle:
while OEnum.next(1, colItem, iValue) = 0 do
begin
Form1.cbxPrinterName.Items.Add(colItem.Properties_.Item(wmiProperty, 0));
end;
Dans cet exemple nous ajoutons chaque nom d’imprimante dans un contrôle de type
Voilà nous savons maintenant comment accéder à WMI à partir du Pascal Objet sous Delphi.
IV Conclusion
Nous avons vu qu’il «était possible également d’accéder à WMI via Delphi. Même si l’approche est un peu différente de celle utilisée avec le framework .Net ceci est malgré tout réalisable. Cela semble plus complexe au premier abord, mais maintenant que la méthode d’accès est connue, il vous sera plus facile de réaliser des requêtes plus complexes.