Accueil
Rechercher:
sur developpez.com sur les forums
Forums | Tutoriels | F.A.Q's | Participez | Hébergement | Contacts
Club Emploi Blogs   TV   Dév. Web PHP XML Python Autres 2D-3D-Jeux Sécurité Windows Linux PC Mac
Accueil Conception Java DotNET Visual Basic  C  C++ Delphi MS-Office SQL & SGBD Oracle  4D  Business Intelligence
FORUMS DELPHI F.A.Q DELPHI TUTORIELS DELPHI LIVRES COMPOSANTS SOURCES DEFI TELECHARGEZ DELPHI TV

Windows Management Instrumentation ( WMI ), seconde partie.

26/06/2004

Par Laurent Dardenne (home page)
 

Cet article a pour objectif de mettre en pratique, sous Delphi, les aspects abordés dans l'article "Windows Management Instrumentation ( WMI ), première partie.".


1. Public concerné
1.1. Le code sources des exemples
2. Opérations de base
2.1. Gérer les erreurs WMI
2.2. Comment contrôler les résultats ?
3. Se connecter à WMI
4. Récupérer une collection d’instances d’objet
5. Enumérer une collection WMI
6. Afficher le contenu d’un objet
6.1. Retrouver le path d'un objet
7. Récupérer une instance ou une définition de classe
8. Récupérer une collection de propriétés
9. Récupérer une collection de qualificateurs
10. Récupérer une collection de méthodes
11. Récupérer un élément d’une collection en utilisant son nom
12. Afficher une propriété
12.1. Gestion des différents types de donnée
13. Modifier une propriété
14. Mettre à jour un objet dans le référentiel WMI
15. Exécuter une requête WQL
16. Modifier les privilèges de sécurité
17. Exécuter une méthode
18. Exécuter une requête d’événement WQL synchrone
19. Récupérer une notification d’événement synchrone
20. Exécuter une requête d’événement WQL asynchrone
23. Récupérer une notification d’événement asynchrone
22. Où trouver des informations sur les classes WMI disponibles ?
23. Windows Management Instrumentation ( WMI ), première partie.


1. Public concerné


Débutant Avancé Expert
[ ]___[X] [X]___[ ] [ ]___[ ]
Testé avec Delphi 5 sous XP pro.
Version 1.0
Dernière mise à jour, le 26/06/2004


1.1. Le code sources des exemples


Vous trouverez ici une suite d'exemples en Delphi concernant la manipulation des objets de scripting WMI.J'ai fait en sorte d'ajouter le plus d'informations possible sur les méthodes et leurs paramètres.
Ce code vous permettra d'aborder simplement et progressivement WMI.
Merci d'utiliser le forum Delphi pour toutes demande autre que les bugs et erreurs de documentation.

Sources des exemples.


2. Opérations de base


Il ne faut pas confondre les objets des API WMI ( SwbemLocator, SwbemObject,SwbemServices,…) et les classes d’objet ou les instances d’objet du référentiel WMI (Win32_Directory, Win32_Process, …).

Les premiers de type TObject ou COM sont manipulables directement sous Delphi.
Exemple :

WmiService:= WMILocator.ConnectServer('.', 'ROOT\CIMV2', '', '', '','', wbemConnectFlagUseMaxWait, nil);
Les seconds ne sont pas manipulables directement sous Delphi.
L’exemple suivant n’est pas possible :

Var NewProcess: Win32_Process; Begin NewProcess.Create('Notepad.exe','c:\temp',Nil, ProcessId); End;
On doit utiliser un objet conteneur de type SwbemObject qui permettra de manipuler les propriétés et méthodes des classes d’objet et d’instances d’objet.

A noter que le VBScript permet une manipulation plus simple des propriétés et méthode des classes d’objet et d’instances d’objet.


2.1. Gérer les erreurs WMI


On utilise un objet TSWbemLastError qui nous informe sur les causes de l'erreur SI une erreur WMI est disponible.
Dans le cas contraire la méthode Connect permettant de se connecter à l'objet COM, déclenchera une exception.

begin Try WMILastError:=TSWbemLastError.Create(AOwner); WMILastError.ConnectKind := ckNewInstance; WMILastError.Connect; Result:=True; Except on E:EOleSysError do begin // Si aucune erreur existe le code d'erreur est égal à E_FAIL = $80004005 Result:=False; FreeAndNil(WMILastError); end end; end;

2.2. Comment contrôler les résultats ?


Je vous recommande dans les premiers temps d'utiliser en paralléle les outils WMI de Microsoft qui vous permettront de vérifier si votre code WMI renvoie les mêmes informations.

Cf. Windows Management Instrumentation ( WMI ), première partie.", chapitre Paramètrage WMI et outils divers.


3. Se connecter à WMI


Pour se connecter à WMI on utilise un composant TSWbemLocator.
La méthode ConnectServer établi une connexion au référentiel WMI dans un espace de nom particuliers, dans l'exemple suivant on se connecte dans l'espace de nom ROOT\CIMV2.

La modification du curseur de la souris indique à l’utilisateur la phase de connexion au référentiel WMI. L’utilisation du flag wbemConnectFlagUseMaxWait évite une attente indéfinie en cas d’indisponibilité de la machine distante.

Si l’appel de la méthode ConnectServer réussi , elle renvoie un objet SwbemServices initialisé, sinon le traitement ne peut se poursuivre.

Var WMILocator: TSWbemLocator; WmiService: SWbemServices; OldCursor: TCursor; begin WMILocator:= TSWbemLocator.Create(self); try OldCursor := Screen.Cursor; Screen.Cursor := crSQLWait; WmiService:= WMILocator.ConnectServer('.', 'ROOT\CIMV2', '', '', '', '', wbemConnectFlagUseMaxWait, nil); Finally WMILocator.Free; Screen.Cursor:= OldCursor; end; end;

4. Récupérer une collection d’instances d’objet


Une fois un objet SWbemServices initialisé, on utilise sa méthode .InstancesOf.
Elle renvoie, dans un objet SwbemObjectSet, une collection d’instances de la classe spécifiée.

Var WmiService: SWbemServices; wmiObjectSet: SWbemObjectSet; Begin … wmiObjectSet := wmiService.InstancesOf('Win32_OperatingSystem', wbemFlagReturnWhenComplete, Nil); … end ;

5. Enumérer une collection WMI


Une fois une collection récupérée, on utilise une interface IEnumVariant qui implémente des fonctions d’énumération sur des données de type variant.
Elle nécessite le transtypage suivant sur un objet de type collection, ici WmiObjectSet :

ObjectEnumerator:= (WmiObjectSet._NewEnum) as IEnumVariant;
La méthode .Next permet une itération pour un ou plusieurs éléments. Elle renvoie S_OK tant qu’il reste des éléments à extraire.
L’élément récupéré de type OleVariant doit à son tour être transtypé pour permettre de le manipuler correctement :

WmiObject := IUnknown(ArrayVariant) as SWBemObject;
Ici l’objet ArrayVariant est transtypé vers la variable WmiObject de type SWBemObject.
On peut ensuite utiliser les propriétés et méthodes de la variable WmiObject .

Le transtypage de l’élément récupéré doit correspondre au type d’objet de la collection, par exemple pour une variable WmiProperty de type SWBemProperty :

WmiProperty:=IUnknown(ArrayVariant) as SWBemProperty;
Var WmiObject: SWbemObject; wmiObjectSet: SWbemObjectSet; ObjectEnumerator: IEnumVariant; ArrayVariant: OleVariant; NumberItem: LongWord; Begin …. // Affecte un énumérateur pour la collection d'objet SWbemObject ObjectEnumerator:= (WmiObjectSet._NewEnum) as IEnumVariant; // Retourne NumberItem éléments dans le tableau ArrayVariant, // ici 1 élément est demandé while (ObjectEnumerator.Next(1, ArrayVariant, NumberItem) = S_OK) do begin // Récupére de la collection l'objet SWbemObject courant WmiObject := IUnknown(ArrayVariant) as SWBemObject; // Retrouve la propriétés de l'instance au format MOF Memo1.Lines.Add(AdjustLineBreaks(wmiObject.GetObjectText_(0))); end;

6. Afficher le contenu d’un objet


La méthode .GetObjectText_ d’un objet SwbemObject renvoie presque toutes les informations d’un objet ( classe ou instance).
Le texte reçu est au format MOF (Managed Object Format) et doit être reformaté en raison de fin de ligne incomplète ( CR /LF ).

Memo1.Lines.Add(AdjustLineBreaks(wmiObject.GetObjectText_(0)));

6.1. Retrouver le path d'un objet


L'objet SWbemObjectPath permet de retrouver des informations sur un objet.

// Retrouve l'objet SWbemObjectPath contenant toutes les propriétés WmiObjectPath:= WmiObject.Path_; // retrouve le nom de la classe via le chemin d'accés relatif. ClasseList.Add(WmiObjectPath.RelPath);

7. Récupérer une instance ou une définition de classe


Une fois un objet SWbemServices initialisé, on utilise sa méthode .Get.
Elle renvoie, dans un objet SwbemObject, une instance ou une définition de classe si le paramètre strObjectPath contient respectivement un chemin d’objet d’instance ou un chemin d’objet de classe.

Chemin d’objet d’instance

WmiObject:= Service.Get(' Win32_Directory.Name="c:\windows\system32\wbem", 0, nil);
La propriété Name étant ici la clé de l’instance.

Chemin d’objet de classe

WmiObject:=WmiService.Get('Win32_ Directory ',0,Nil);

8. Récupérer une collection de propriétés


La propriété Properties_ de l’objet SWbemObject renvoie une collection de type SwbemPropertySet contenant toutes les propriétés de la classe ou de l’instance d’objet.

Var ListePropriétés : SwbemPropertySet ; WmiObjet : SWbemObject ; Begin ListePropriétés := WmiObjet.Properties_;

9. Récupérer une collection de qualificateurs


La propriété Qualifiers_ de l’objet SWbemObject renvoie une collection de type SwbemQualifiersSet contenant toutes les propriétés de la classe ou de l’instance d’objet.

Var ListeQualificateurs : SwbemQualifiersSet ; WmiObjet : SWbemObject ; Begin ListeQualificateurs := WmiObjet.Qualifiers_;

10. Récupérer une collection de méthodes


La propriété Methods_ de l’objet SWbemObject renvoie une collection de type SwbemMethodsSet contenant toutes les propriétés de la classe ou de l’instance d’objet.

Var ListeMethodes : SwbemMethodsSet ; WmiObjet : SWbemObject ; Begin ListeMethods := WmiObjet.Methods_;

11. Récupérer un élément d’une collection en utilisant son nom


La méthode .Item d’un objet collection permet d’extraire un élément par son nom.

WmiProperty:= Instance.Properties_.Item('CommandLine',0);

12. Afficher une propriété


Un objet SWBemProperty représente une propriété de classe. Cet objet possède la propriété Name qui contient le nom de la propriété manipulée.
Avant de récupérer sa valeur par la méthode .Get_Value, on doit lire la propriété CIMType qui détermine le type de donnée de la propriété manipulée puis la convertir vers une chaîne de caractères.

Ici la propriété de nom Description est de type string ( wbemCimtypeString ), on peut donc directement l’insérer dans un TMemo.

... If WmiProperty.name='Description' then if WmiProperty.CIMType=wbemCimtypeString then Memo1.Lines.Add(WmiProperty.Get_Value); else Convertion ...

12.1. Gestion des différents types de donnée


Voici une fonction de convertion prenant en charge tous les types de donnée possible pour la propriété CIMType.

Function WMIPropertyToStr(WmiService:SWbemServices; WmiProperty : SWbemProperty):String; var sValue: String; Count: Integer; Value: Variant; WmiObjet : SWbemObject; begin try Value:=WmiProperty.Get_Value; sValue := ''; if VarIsNull(Value) then sValue := 'Is Null' else try case WmiProperty.CIMType of wbemCimtypeSint8, wbemCimtypeUint8, wbemCimtypeSint16, wbemCimtypeUint16, wbemCimtypeSint32, wbemCimtypeUint32, wbemCimtypeSint64, wbemCimtypeUint64: if VarIsArray(Value) then begin if VarArrayHighBound(Value, 1) > 0 then for Count := 1 to VarArrayHighBound(Value, 1) do sValue := sValue + ' ' + IntToStr(Value[Count]); end else sValue := IntToStr(Value); wbemCimtypeReal32, wbemCimtypeReal64: sValue := FloatToStr(Value); wbemCimtypeBoolean: if Value then sValue := 'True' else sValue := 'False'; // Single 16-bit Unicode character in Universal Character Set–2 (UCS-2) format wbemCimtypeChar16, // Unicode character string wbemCimtypeString: if VarIsArray(Value) then begin if VarArrayHighBound(Value, 1) > 0 then try for Count := 1 to VarArrayHighBound(Value, 1) do sValue := sValue + ' ' + Value[Count]; except on E: EConvertError do ShowMessage(E.Message); end; end else sValue := Value; wbemCimtypeDatetime: sValue := Value; // Référence d'objet, le chemin de l'objet peut être // un nom complet serveur\espace de nom // ou relatif dans le même espace de nom wbemCimtypeReference: begin // Récupére l'objet référençé WmiObjet:=WmiService.Get(Value,wbemFlagReturnWhenComplete,Nil); sValue:=AdjustLineBreaks(WmiObjet.GetObjectText_(0)) end; // Objet imbriqué // Renvoie le path de la propriété de type Objet wbemCimtypeObject: begin // Récupére l'objet imbriqué WmiObjet:=IUnknown(WmiProperty.Get_Value) as SWbemObject ; sValue:=WmiObjet.Path_.Relpath; end; end; // case except on E: EVariantError do ShowMessage('WMIPropertyToStr : Erreur de convertion de variant'); end; Finally Result:=sValue; end; end;

13. Modifier une propriété


La méthode .Set_Value permet de modifier le contenue d’une propriété.

Dans l’exemple suivant on modifie la propriété CommandLine de la méthode .Create de la classe Win32_Process.

Var PropertyCommandLine: OleVariant; Instance_inParameters: SWbemObject; Begin WmiProperty:= Instance_inParameters.Properties_.Item('CommandLine',0); PropertyCommandLine:= 'Notepad.exe'; WmiProperty.Set_Value(PropertyCommandLine);
Dans l’unité Delphi la déclaration de la propriété Value de l’objet SWBemProperty n’existe pas, utilisez la méthode .Set_Value.


14. Mettre à jour un objet dans le référentiel WMI


Une fois un objet modifié, exécutez sa méthode .Put_ afin de le modifier dans le référentiel WMI.

Var WmiObject: SWbemObject; PropertyMaxFileSize: SWbemProperty; MaxFileSize : OleVariant; Begin // Retrouve la propriété à modifier PropertyMaxFileSize:= WmiObject.Properties_.Item('MaxFileSize',0); // Nouvelle valeur de la propriété MaxFileSize:= 512000; // 512 Ko (unité byte) //Renseigne la valeur de la propriété PropertyMaxFileSize.Set_Value(MaxFileSize); // Mise à jour de l'instance courante WmiObject.Put_(wbemFlagReturnWhenComplete,Nil) ;

15. Exécuter une requête WQL


La méthode .ExecQuery de l’objet SwbemServices permet d’interroger le référentiel en exécutant une requête WQL synchrone.
Cette méthode renvoie une collection de type SwbemObjectSet contenant des objets correspondants à la requête.
Le premier paramètre peut être une variable chaîne de caractère.

var WmiService: SWbemServices; WmiObject: SWbemObject; wmiObjectSet: SWbemObjectSet; ObjectEnumerator: IEnumVariant; ArrayVariant: OleVariant; // Tableau de variant NumberItem: LongWord; begin … WmiObjectSet := wmiService.ExecQuery('SELECT Name FROM Win32_Service Where State=''Stopped''', 'WQL', wbemFlagReturnImmediately, nil);

16. Modifier les privilèges de sécurité


La propriété Security_ d'un objet SWbemServices contient la collection Privileges contenant des objets de type SWbemPrivilege permet de modifier les priviléges de sécurité.

Dans l'exemple suivant on ajoute le privilège 'Shutdown' avant d'exécuter la méthode Win32Shutdown de la classe Win32_OperatingSystem.

WmiServices.Security_.Privileges.Add(wbemPrivilegeShutdown, True);

17. Exécuter une méthode


La méthode ExecMethod_ d’un objet SWbemObject permet d’exécuter une méthode de classe ou d’instance. Cette méthode renvoie un objet qui contient la valeur de retour et les paramètres modifiés.

Mais son exécution nécessite quelques traitements préliminaires.
Retrouver la définition, de la classe ou de l’instance concernée, par le méthode .Get.
Modifier si besoin les privilèges de sécurité nécessaires à l'appel de méthode.
Récupérer, à partir de la collection Methods_ , les propriétés de la méthode que vous souhaitez exécuter. Pour ce faire vous pouvez utiliser la méthode .Item.
Créer une nouvelle instance de la méthode de la classe concernée en utilisant la méthode .SpawnInstance_ . Cette création alloue l'espace mémoire pour manipuler les paramètres de cette méthode. La collection InParameters.properties_ contient le nombre, le nom et le type des paramètres de cette nouvelle instance de méthode.
Renseigner les paramètres de la méthode avec les valeurs appropriées.
Appeler la méthode .ExecMethod_.

Et enfin si vous souhaitez contrôler les valeurs de retour de la méthode consulter les propriétés de l’objet renvoyé par l‘exécution de la méthode .ExecMethod_.

var WMILocator: TSWbemLocator; Process, NewProcess, Instance_inParameters: SWbemObject; WmiProperty: SWbemProperty; ProcessMethod: ISWbemMethod; PropertyCommandLine, PropertyReturnValue, ProcessID OleVariant; begin WMILocator:= TSWbemLocator.Create(self); try // Création d'une connexion à un espace de nom local // ici le nom de l'espace de nom cible est : CIMV2 // L'appel renvoie un pointeur sur un objet SWbemServices WmiService:= WMILocator.ConnectServer('.', 'ROOT\CIMV2', '', '', '', '', wbemConnectFlagUseMaxWait, nil); // Retrouve la définition de la classe Win32_Process // Sur le site de MS, la classe Win32_Process se trouve dans : // Win32 Classes.Operating system Classes.Process Process:=WmiService.Get('Win32_Process',0,Nil); // Si vous devez modifier la sécurité nécessaire à l'appel de méthode, // par exemple 'Shutdown' utilisez : // wmiServices.Security_.Privileges.Add(wbemPrivilegeShutdown, True); // Récupére, à partir de la collection de méthode, // la définition de la méthode 'Create' de la classe Win32_Process // qui correspond à ceci : { Win32_Process.Create(IN CommandLine string , IN CurrentDirectory string , IN ProcessStartupInformation Win32_ProcessStartup , OUT ProcessId uint32) Valeur de retour : [Out] ProcessId uint32 ; [out] ReturnValue uint32 ; } ProcessMethod:=Process.Methods_.Item('Create', 0); // Crée une nouvelle instance de la méthode '.Create' de la classe Win32_Process // alloue l'espace mémoire pour manipuler ces paramètres. // ProcessMethod.InParameters.Properties_ contient la liste des paramètres de la méthode Instance_inParameters:= ProcessMethod.InParameters.SpawnInstance_(0); // Retrouve la propriété 'CommandLine' de la méthode '.Create' WmiProperty:= Instance_inParameters.Properties_.Item('CommandLine',0); // Nom du programe à exécuter PropertyCommandLine:= 'Notepad.exe'; //Renseigne la valeur de la propriété 'CommandLine' de la méthode '.Create' WmiProperty.Set_Value(PropertyCommandLine); //Crée un process Via la Méthode '.Create' NewProcess:= Process.ExecMethod_('Create', Instance_inParameters, wbemFlagReturnWhenComplete, nil); { Un objet OutParameters est créé par la méthode exécutée } // Recupére la valeur de retour de la méthode via la propriété 'ReturnValue' PropertyReturnValue:= NewProcess.Properties_.Item('ReturnValue', 0); if PropertyReturnValue.Value = 0 then begin // Réutilise la propriété pour récupérer l'ID de process PropertyReturnValue:= NewProcess.Properties_.Item('ProcessId', 0); ProcessID:=PropertyReturnValue.Value; MessageBox(0, PChar('Process crée.'+#10#13+'Pid : '+inttostr(ProcessID)), PChar(Form1.Caption), MB_OK); end else MessageBox(0, PChar('Erreur '+inttostr(PropertyReturnValue.Value)+' lors de la création du process.'), PChar(Form1.Caption), MB_OK); Finally WMILocator.Free; end;

18. Exécuter une requête d’événement WQL synchrone


La méthode .ExecNotificationQuery de l’objet SwbemServices permet d’interroger le référentiel périodiquement ( polling ) en exécutant une requête WQL d’événement synchrone.
Le polling de l’événement se fait dans l’intermédiaire de WMI et non par un provider.

Cette méthode renvoie un objet de type SwbemEventSource.
La notification d’événement se faisant via l’appel de sa méthode .NextEvent.
L‘intervalle de polling recommandé est de 300 secondes pour éviter de monopoliser les ressources de la machine.
Dans cet exemple on souhaite récupérer les événements de suppression d’instance de process en utilisant la classe d’événement __instancedeletionevent sur la propriété TargetInstance de classe Win32_Process.

Seul les événements concernant les instances de process en cours ayant changées pendant l’intervalle de polling seront détectés.

Si après l’exécution de la requête et pendant l’intervalle de polling de 300 secondes, vous exécutiez une application puis la supprimiez tout de suite après, un événement __instancedeletionevent est déclenché dans le référentiel WMI.
Mais cet événement ne sera pas 'vue' par la requête, car le contexte ( nombre de process ) ne présentera aucun changement entre le moment où la requête est exécutée par la méthode .ExecNotificationQuery et le moment où l’intervalle de polling se déclenche afin de contrôler si un événement attendu c’est produit.
Il n’a donc pas, avec ce type de requête, d’historique des événements déclenchés pendant la durée du polling.

Le premier paramètre peut être une variable chaîne de caractères.

Var WmiMonitoredProcesses: SWbemEventSource; WmiLatestProcess, WmiObjet: SWbemObject; Query : String; Begin // Recherche les événements de type '__instancedeletionevent' ( Intrinsèque ). // WMI effectue le polling toute les 1 secondes. // Seule les instances de la classe Win32_Process sont concernées. Query:='Select * from __instancedeletionevent within 1 where TargetInstance isa "Win32_Process"'; WmiMonitoredProcesses:=WMIService.ExecNotificationQuery(Query, 'WQL', wbemFlagForwardOnly + wbemFlagReturnImmediately, Nil);

19. Récupérer une notification d’événement synchrone


La notification d’événement se fait par l’appel de la méthode .NextEvent d’un objet de type SwbemEventSource.
Cette méthode est bloquante car elle attend un événement avant de se terminer.

Si un événement est disponible elle le retrouve et renvoie un objet SWbemObject contenant une instance de la classe d’événement demandé par la requête associée.

Var WmiMonitoredProcesses: SWbemEventSource; WmiLatestProcess, WmiObjet: SWbemObject; Query : String; Begin Query:='Select * from __instancedeletionevent within 1 where TargetInstance isa "Win32_Process"'; WmiMonitoredProcesses:=WMIService.ExecNotificationQuery(Query, 'WQL', wbemFlagForwardOnly + wbemFlagReturnImmediately, Nil); // Renvoie une classe de type '__InstanceDeletionEvent' // -1 = Attente indéfinie. Le traitement attend un événement... WmiLatestProcess:= WmiMonitoredProcesses.NextEvent(-1); // Retrouve l'objet contenue dans la propriété TargetInstance // à partir de l'objet crée par la méthode WmiMonitoredProcesses.NextEvent // L'objet retrouvé contient une copie de l'instance du process supprimé. WmiObjet:=IUnknown(WmiLatestProcess.Properties_.Item('TargetInstance',0).Get_Value) as SWbemObject;

20. Exécuter une requête d’événement WQL asynchrone


Ajouter un composant TSWbemSink sur votre fiche. Renseignez ces gestionnaires d'événements :

OnCompleted est déclenché quand une opération asynchrone est terminée, l'appel de la méthode TSWbemSink.Cancel déclenche cet événement.

OnObjectPut est déclenché après une opération PUT asynchrone, ie. aprés mise à jour d'un instance ou d'une classe.

OnProgress est déclenché pour fournir le statut d'une opération asynchrone. Attention, cet événement n'est pas pris en charge par tous les providers.

OnObjectReady est déclenché quand un objet, fourni par un appel asynchrone est disponible. C'est cet événement qui sera le plus utilisé.

La méthode .ExecNotificationQueryAsync de l’objet SwbemServices permet d’interroger le référentiel périodiquement ( polling ) en exécutant une requête WQL d’événement asynchrone.
Elle similaire à la méthode .ExecNotificationQuery en dehors du fait que l'on doit spécifier un Object collecteur qui reçoit de WMI les notifications d'événements asynchrone et les renvoie vers le client.

A noter que le collecteur peut gérer les événements de plusieurs requêtes asynchrone.

Le code suivant exécute la requête de polling et déclenche la collecte des événements effectué par le composant TSWbemSink.

Vous devez renseigner le paramètre iFlags de l'appel asynchrone avec la valeur wbemFlagSendStatus si vous voulez recevoir des mises à jour de statut, autrement cet événement n'est pas déclenché. Sous réserve que le provider gére les événements de mises à jour de statut.

var Query: String; begin Query:='Select * from __instancedeletionevent within 1 where TargetInstance isa "Win32_Process"'; WMIService.ExecNotificationQueryAsync(SWbemSink1.DefaultInterface, Query, 'WQL', wbemFlagSendStatus, Nil, Nil); end;

23. Récupérer une notification d’événement asynchrone


La notification d’événement se fait via le gestionnaire d'évenement TSWbemSink.OnObjectReady d’un objet de type TSWbemSink.
Dés qu'un objet est disponible WMI déclenche cet événement et renvoie un objet contenant une instance de la classe demandé par la requête associée.

Dans l'exemple suivant le code est lié à la requête suivante :

Select * from __instancedeletionevent within 1 where TargetInstance isa "Win32_Process"
L'objet reçu, objWbemObject, est une instance de la classe '__InstanceDeletionEvent'.
On doit donc transtyper sa propriété TargetInstance pour récupérer la copie de l'instance du process supprimé.

procedure TForm1.SWbemSink1ObjectReady(Sender: TObject; var objWbemObject, objWbemAsyncContext: OleVariant); // Déclenché lorsqu'un objet fourni par l'appel asynchrone est disponible. // ObjWbemObject contient l'objet retourné var WmiObjet: ISWbemObject; begin // L'objet retourné contient une copie de l'instance du process supprimé. WmiObjet:=IUnknown(objWbemObject.Properties_.Item('TargetInstance',0).Value) as ISWbemObject; Memo1.Lines.Add(#13#10+'Le process '+WMIVariantToStr(WmiObjet.Properties_.Item('Name',0).Get_Value)+ ' s''est terminé.'+#13#10); Memo1.Lines.Add(WmiObjet.Path_.path); Memo1.Lines.Add(AdjustLineBreaks(WmiObjet.GetObjectText_(0))); end;

22. Où trouver des informations sur les classes WMI disponibles ?


Liste et définitions des classes WMI.

Par exemple vous trouverez des informations sur Windows dans une des catégories de base nommée Win32 Classes qui contient les sous-catégories suivantes :

  • Computer system hardware
  • Operating system Classes
  • Installed applications
  • WMI service management
  • Performance counters


23. Windows Management Instrumentation ( WMI ), première partie.


Article précédent
Les bases de WMI.



Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La licence d'utilisation Open Content ( http://opencontent.org/opl.shtml) vous permet d'utiliser librement les documents publiés sur mon espace personnel à condition de mentionner clairement le nom de son auteur avec un lien sur mon espace personnel de ce site et de garder son caractère "Open Content".

Responsables bénévoles de la rubrique Delphi : Nono40 et Pedro - Contacter par EMail :
Vos questions techniques : forum d'entraide Delphi - Publiez vos articles, tutoriels et cours
et rejoignez-nous dans l'équipe de rédaction du club d'entraide des développeurs francophones
Nous contacter - Copyright © 2000-2008 www.developpez.com - Legal informations.