FAQ DelphiConsultez toutes les FAQ
Nombre d'auteurs : 124, nombre de questions : 933, dernière mise à jour : 28 septembre 2024 Ajouter une question
Cette FAQ a été réalisée à partir des questions fréquemment posées sur les forums Delphi et Delphi et bases de données de www.developpez.com et de l'expérience personnelle des auteurs.
Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose soient correctes. Les auteurs font le maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous souhaitez y apporter des corrections ou la compléter, contactez un responsable (lien au bas de cette page).
Nous espérons que cette FAQ saura répondre à vos attentes. Nous vous en souhaitons une bonne lecture.
L'équipe Delphi de Developpez.com.
- Qu'est-ce qu'un provider WMI ?
- Qu'est-ce qu'un événement sous WMI ?
- Qu'est-ce que l'objet WMI SWbemSink ?
- Comment recevoir un évènement synchrone WMI ?
- Comment recevoir un événement asynchrone WMI ?
- Comment collecter les informations de plusieurs requêtes d'évènements asynchrones ?
- Comment gérer plusieurs types d'évènement d'une requête?
WMI propose des données sur des objets managés par Windows au travers de providers. Un provider (fournisseur de données) est un objet COM qui agit en tant qu'intermédiaire entre WMI et un objet géré.
Au travers de WMI, une application peut demander et envoyer des informations vers l'objet géré.
Un provider retrouve les données d'un composant système, tel qu'un process ou SNMP ou encore IIS et renvoie ces informations de WMI vers une application cliente.
Exemples :
- quand une application ou un script demande des informations sur un processus en utilisant la classe WMI Win32_Process, les données sont obtenues dynamiquement via le provider pré-installé.
- une application peut modifier et rechercher des informations de la base de registres via WMI par l'intermédiaire du provider nommé System Registry Provider.
Il existe plusieurs types de provider :
- Provider d'instance
cf. classe __InstanceProviderRegistration - Provider de classe
cf. classe __ClassProviderRegistration - Provider de méthode
cf. classe __MethodProviderRegistration - Provider de propriété
cf. classe __PropertyProviderRegistration - Provider d'événement
cf. classe __EventProviderRegistration - Provider d'événement client
cf. classe __EventConsumerProviderRegistration
Par exemple le fichier C:\WINDOWS\system32\wbem\msiprov.dll héberge le provider pour MSI.
Les événements de WMI sont des occurrences qui correspondent aux situations qui surviennent soit dans le monde réel, soit lors de changements dans le référentiel CIM géré par le manager d'objet CIM (CIMOM, Common Information Model Object Manager).
Après un événement, une notification le concernant est générée soit par un provider d'événement, soit par le manager d'objet CIM lui-même. Les notifications sont fournies par le manager d'objet CIM à un ou plusieurs destinataires enregistrés connus comme clients d'événements.
- Les providers d'événement envoient des notifications en réponse aux occurrences d'événement, que des clients soient ou non enregistrés.
- Les clients d'événement s'enregistrent pour recevoir des notifications sans savoir comment et par qui les événements et leurs notifications correspondantes sont fournis.
Les clients s'enregistrent pour recevoir des notifications en indiquant un filtre, créé en utilisant le langage d'interrogation WQL de WMI. La requête décrit les conditions dans lesquelles le client est configuré pour recevoir une notification.
L'objet TSWbemSink (collecteur) est implémenté par des applications clientes pour recevoir les résultats des opérations asynchrones et des notifications d'événements.
Pour effectuer un appel asynchrone, vous devez créer une instance d'un objet TSWbemSink et le passer en paramètre, souvent nommé ObjWbemSink, aux méthodes nécessitant ce type d'objet.
Par exemple SWbemServices.ExecNotificationQueryAsync.
Les évènements dans votre implémentation de TSWbemSink sont déclenchés quand le statut ou les résultats sont retournés ou que l'appel est terminé.
Les gestionnaires d'évènements Delphi sont :
- OnCompleted est déclenché quand une opération asynchrone est terminée.
- OnObjectPut est déclenché après une opération PUT asynchrone.
- OnObjectReady est déclenché quand un objet résultant d'un appel asynchrone est disponible.
- OnProgress est déclenché pour fournir le statut d'une opération asynchrone.
Si les événements sont produits à partir d'un provider qui implémente les mises à jour de statut, vous pouvez gérer l'événement OnProgress pour informer les utilisateurs à propos d'un changement de statut lors d'une opération asynchrone.
La méthode Cancel annule toutes les opérations asynchrones liées à l'instance.
L'exemple suivant initialise un client d'évènement temporaire asynchrone recherchant les fins de processus.
La variable
Code delphi : | Sélectionner tout |
WMILocator: TSWbemLocator;
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | procedure TForm1.BtConnexionClick(Sender: TObject); var WmiService: SWbemServices; WmiObjet: SWbemObject; Query: String; begin WMILocator:= TSWbemLocator.Create(self); WmiService:= WMILocator.ConnectServer('.', 'ROOT\CIMV2', '', '', '', '', wbemConnectFlagUseMaxWait, nil); // Recherche les événements de type // '__instancedeletionevent' ( Intrinsèque ) Query:='Select * from __instancedeletionevent within 1 where TargetInstance isa "Win32_Process"'; // On passe à cette méthode l'Object collecteur qui reçoit // les notifications d'événements asynchrones. WMIService.ExecNotificationQueryAsync(CollecteurEvenement.DefaultInterface, Query, 'WQL', wbemFlagSendStatus, Nil, Nil); |
Vous pouvez consulter ce tutoriel pour de plus amples informations sur les gestion des événements d'un objet COM.
Avant de supprimer l'objet ISWbemSink on doit appeler la méthode CollecteurEvenement.Cancel. Cet appel déclenche l'événement OnCompleted.
La propriété DefaultInterface étant une interface sa libération est donc automatique.
L'appel implicite de la méthode Disconnect n'est pas nécessaire car il est effectué automatiquement lors de libération de l'interface.
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 | procedure TForm1.FormDestroy(Sender: TObject); begin // libère les ressources WMI CollecteurEvenement.Cancel WMILocator.Free; end; |
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 | procedure TForm1.btCancelSinkClick(Sender: TObject); Var WMILastError: TSWbemLastError; begin CollecteurEvenement.Cancel; if ExistWmiErreur(WMILastError,Self) then begin ShowWMIErreur('Erreur dans la méthode Cancel du collecteur.',WMILastError,Nil); // appel de WMILastError.Release automatique par Delphi end; end; |
Note:
Un seul objet de ce type peut être utilisé pour collecter les informations de plusieurs requêtes d'événements asynchrones.
Voici le code associé aux procédures d'événements de l'objet nommé CollecteurEvenement :
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | procedure TForm1.CollecteurEvenementCompleted(Sender: TObject; iHResult: TOleEnum; const objWbemErrorObject: ISWbemObject; const objWbemAsyncContext: ISWbemNamedValueSet); //Déclenché lorsqu'une opération asynchrone est terminée. var S:String; begin // Consultez le SDK pour le détail des codes d'erreurs Memo1.Lines.Add('Opération asynchrone terminée.'); If iHResult<> WBEM_S_NO_ERROR then //ShowWMIErreur('Collecteur événement Completed',objWbemErrorObject,nil ); begin S:='Informations d''erreur WMI :'+#13#10+#13#10+ 'Collecteur événement Completed'+#13#10+ 'Operation : '+objWbemErrorObject.Properties_.Item('Operation',0).Get_Value+#13#10+ 'Provider : '+objWbemErrorObject.Properties_.Item('ProviderName',0).Get_Value+#13#10+ 'Description : '+WMIVariantToStr(objWbemErrorObject.Properties_.Item('Description',0).Get_Value)+#13#10+ 'parametre : '+WMIVariantToStr(objWbemErrorObject.Properties_.Item('ParameterInfo',0).Get_Value)+#13#10+ 'Code : '+WMIVariantToStr(objWbemErrorObject.Properties_.Item('StatusCode',0).Get_Value); ShowMessage(S); end; end; procedure TForm1.CollecteurEvenementObjectPut(Sender: TObject; const objWbemObjectPath: ISWbemObjectPath; const objWbemAsyncContext: ISWbemNamedValueSet); //Déclenché aprés une opération PUT asynchrone. begin Memo1.Lines.Add('Opération Put .'); end; procedure TForm1.CollecteurEvenementObjectReady(Sender: TObject; const objWbemObject: ISWbemObject; const objWbemAsyncContext: ISWbemNamedValueSet); //Déclenché lorsqu'un objet fourni par l'appel asynchrone est disponible. // objWbemObject contient l'objet retourné var WmiObjet: SWbemObject; begin // Retrouve l'objet contenu dans la propriété TargetInstance // qui contient une copie de l'instance du process supprimé. WmiObjet:=IUnknown(objWbemObject.Properties_.Item('TargetInstance',0).Get_Value) as SWbemObject; Memo1.Lines.Add('Le process '+WMIVariantToStr(WmiObjet.Properties_.Item('Name',0).Get_Value)+ ' est terminé.'+#13#10); Memo1.Lines.Add(WmiObjet.Path_.path); Memo1.Lines.Add(AdjustLineBreaks(WmiObjet.GetObjectText_(0))); end; procedure TForm1.CollecteurEvenementProgress(Sender: TObject; iUpperBound, iCurrent: Integer; const strMessage: WideString; const objWbemAsyncContext: ISWbemNamedValueSet); //Déclenché pour fournir l'état de l'opération asynchrone. // Dépend du provider: tous ne semblent pas gérer cet événement. begin // Consultez le SDK pour le détail des paramètres Memo1.Lines.Add('Evénement on Progress'); Memo1.Lines.Add(IntToStr(iCurrent)+'/'+IntToStr(iUpperBound)+' Objet. '+#13#10+strMessage); end; |
WMI contient une infrastructure d'évènements qui génère des notifications lors de changements de données et de services de WMI.
Par exemple, si une application crée un nouvel objet dans le référentiel CIM de WMI, WMI génère un évènement nommé __InstanceCreationEvent.
Vous pouvez créer une requête semi-synchrone ou asynchrone pour surveiller les changements dans l' Event logs, la création de processus, le statut d'un service, la disponibilité d'un ordinateur ou l'espace libre d'un disque, etc.
La notification d'un changement sur les données standards de WMI s'appelle un événement intrinsèque .
Par exemple les évènements __InstanceCreationEvent ou __NamespaceDeletionEvent sont des événements intrinsèques.
La notification d'un changement qu'un provider fait pour définir un évènement le concernant s'appelle un évènement extrinsèque.
Par exemple, les providers System Registry, Power Management Event, et Win32 définissent leurs propres événements.
Typiquement, une classe qui définit un événement a un nom se terminant par le mot Event. Par exemple, le provider Win32 a la classe Win32_NTLogEvent. Quand un provider possède une classe d'événement, vous effectuez une requête pour un événement intrinsèque.
On utilise la méthode SWbemServices.ExecNotificationQuery pour exécuter une requête d'évènement synchrone.
Dans notre exemple nous souhaitons être informés lors d'une suppression d'un process quelconque. La requête WQL se décompose de la maniére suivante :
Code delphi : | Sélectionner tout |
1 2 | //Recherche la suppression d'instance Query:='Select * from __instancedeletionevent within 1 where TargetInstance isa "Win32_Process"'; |
- __instancedeletionevent est une classe représentant un évènement de suppression d'une instance dans le référentiel WMI,
- within 1 indique à WMI d'effectuer un contrôle toutes les 1 secondes,
- TargetInstance est une propriété de type objet de la classe __instancedeletionevent, elle contient l'instance concernée par notre requête,
- isa est un opérateur signifiant à WMI de renvoyer toutes les sous-classes de la classe spécifiée, Microsoft recommande un délai de pooling de 300 secondes afin d'éviter les surchages processeur.
Si après le démarrage du pooling, une application est exécutée puis tout de suite supprimée, pendant ce laps de temps l'événement n'est pas 'vu' par WMI. La requête s'effectue sur les process existants au moment de son exécution.
Pour récupérer l'événement on utilise l'objet SWbemEventSource et plus particulièrement sa méthode NextEvent qui attend et renvoie le premier événement disponible du type attendu.
Cette approche bloque donc le déroulement du programme client.
Voici l'exemple complet :
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | procedure TForm1.BTConnexionClick(Sender: TObject); //Client d'évènement temporaire recherchant les fins de processus. var WMILocator: TSWbemLocator; WmiService: SWbemServices; WmiMonitoredProcesses: SWbemEventSource; WmiLatestProcess, WmiObjet: SWbemObject; OldCursor: TCursor; Query: String; begin WMILocator:= TSWbemLocator.Create(self); try OldCursor := Screen.Cursor; Screen.Cursor := crSQLWait; WmiService:= WMILocator.ConnectServer('.', 'ROOT\CIMV2', '', '', '', '', wbemConnectFlagUseMaxWait, nil); 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éé 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; Memo1.Lines.Add('Le process '+WMIVariantToStr(WmiObjet.Properties_.Item('Name',0).Get_Value)+ ' est terminé.'+#13#10); Memo1.Lines.Add(WmiObjet.Path_.path); Memo1.Lines.Add(AdjustLineBreaks(WmiObjet.GetObjectText_(0))); Finally WMILocator.Free; Screen.Cursor:= OldCursor; end; end; |
En utilisant l'outil FileMon de sysinternals on peut voir les nombreuses lectures sur le référentiel 'C:\WINDOWS\system32\wbem\Repository\FS\INDEX.BTR' effectuées par le process "C:\WINDOWS\System32\svchost.exe -k netsvcs" qui référence le service WinMgmt :%SystemRoot%\system32\wbem\WMIsvc.dll.
Ces lectures se font uniquement lors de la suppression d'un process et pas toutes les secondes comme on pourrait le supposer.
Une fois configuré un objet de type TSWbemSink il reste à créer au minimum les gestionnaires d'événements onReady et onCompleted, les 2 autres sont d'un usage moins courant.
Pour onReady on reçoit les paramètres suivants :
- objWbemObject contient l'objet retourné
- objWbemAsyncContext permet de différencier l'événement reçu dans le cas où l'on utilise plusieurs requêtes d'evénements avec un même collecteur de données.
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | procedure TForm1.CollecteurEvenementObjectReady(Sender: TObject; const objWbemObject: ISWbemObject; const objWbemAsyncContext: ISWbemNamedValueSet); //Déclenché lorsqu'un objet fourni par l'appel asynchrone est disponible. var WmiObjet: SWbemObject; begin // L'objet retrouvé contient une copie de l'instance du process supprimé. WmiObjet:=IUnknown(objWbemObject.Properties_.Item('TargetInstance',0).Get_Value) as SWbemObject; Memo1.Lines.Add('Le process '+WMIVariantToStr(WmiObjet.Properties_.Item('Name',0).Get_Value)+ ' est terminé.'+#13#10); Memo1.Lines.Add(WmiObjet.Path_.path); Memo1.Lines.Add(AdjustLineBreaks(WmiObjet.GetObjectText_(0))); end; |
- iHResult : Indique si l'appel asynchrone à réussi Dans ce cas, il contient la valeur WBEM_S_NO_ERROR (0) sinon il contient code d'erreur.
- objWbemErrorObject : Contient, en cas d'erreur, un objet SWbemLastError.
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | procedure TForm1.CollecteurEvenementCompleted(Sender: TObject; iHResult: TOleEnum; const objWbemErrorObject: ISWbemObject; const objWbemAsyncContext: ISWbemNamedValueSet); //Déclenché lorsqu'une opération asynchrone est terminé. var S:String; begin Memo1.Lines.Add('Opération asynchrone terminée.'); If iHResult<> WBEM_S_NO_ERROR then // Appel asynchrone annulé. // Ce n'est pas une erreur, l'appel de TSWbemSink.Cancel provoque // l'appel de cet événement if iHResult= wbemErrCallCancelled then exit else begin S:='Informations d''erreur WMI :'+#13#10+#13#10+ 'Collecteur événement Completed'+#13#10+ 'Operation : '+objWbemErrorObject.Properties_.Item('Operation',0).Get_Value+#13#10+ 'Provider : '+objWbemErrorObject.Properties_.Item('ProviderName',0).Get_Value+#13#10+ 'Description : '+WMIVariantToStr(objWbemErrorObject.Properties_.Item('Description',0).Get_Value)+#13#10+ 'parametre : '+WMIVariantToStr(objWbemErrorObject.Properties_.Item('ParameterInfo',0).Get_Value)+#13#10+ 'Code : '+WMIVariantToStr(objWbemErrorObject.Properties_.Item('StatusCode',0).Get_Value); ShowMessage(S); end; end; |
- wbemErrFailed : Erreur non spécifié.
- wbemErrOutOfMemory : pas assez de mémoire pour effectuer l'opération.
- wbemErrTransportFailure : Une erreur réseau s'est produite, empêchant le déroulement normal de l'opération.
Dans ce cas, on doit utiliser une collection de valeurs nommées du type TSWbemNamedValue et un collecteur de données.
Ajoutons deux variable dans la partie Public de la fiche :
Code delphi : | Sélectionner tout |
1 2 | ProcessContext : TSWbemNamedValueSet; EventLogContext :TSWbemNamedValueSet; |
Une valeur nommée, une simple chaîne de caractères, nous permettra de différencier, dans la méthode TSWbemSink.OnReady, les évènements que nous souhaitons gérer.
Créons d'abord nos collections :
Code delphi : | Sélectionner tout |
1 2 3 4 5 | Function TForm1.InitContexte( const strName: WideString; var varValue: OleVariant):TSWbemNamedValueSet; begin Result:=TSWbemNamedValueSet.Create(Self); Result.Add(strName,varValue,0) // IFlags tjr zéro end; |
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | procedure TForm1.FormCreate(Sender: TObject); Var value: OleVariant; begin //Collection liée à la gestion des instances de process Win32. //Contenu Value:='Instances'; //'SinkName' est le nom de la valeur nommée et 'Instances' son contenu. ProcessContext:=InitContexte('SinkName',Value); //Collection liée à la gestion de l'eventlog. Value:='EventLog'; EventLogContext:=InitContexte('SinkName',Value); end; |
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | var Query: String; Query2: String; begin Query:='Select * from __InstanceDeletionEvent within 1 where TargetInstance isa "Win32_Process"'; // On utilise le même collecteur pour 2 évènements différents // On ajoute un objet TSWbemNamedValueSet afin de différencier l'événement. WMIService.ExecNotificationQueryAsync(SWbemSink1.DefaultInterface, Query, 'WQL', wbemFlagSendStatus, Nil, ProcessContext.DefaultInterface); Query2:='Select * from __InstanceCreationEvent where TargetInstance isa "Win32_NTLogEvent"'; WMIService.ExecNotificationQueryAsync(SWbemSink1.DefaultInterface, Query2, 'WQL', wbemFlagSendStatus, Nil, EventLogContext.DefaultInterface); end; |
Voici le code permettant de retrouver quel type d'évènement a été déclenché :
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | procedure TForm1.SWbemSink1ObjectReady(ASender: TObject; const objWbemObject: ISWbemObject; const objWbemAsyncContext: ISWbemNamedValueSet); // Déclenché lorsqu'un objet fourni par l'appel asynchrone est disponible. // ObjWbemObject contient l'objet retourné var WmiObjet: ISWbemObject; Contexte : ISWbemNamedValue; WMILastError: TSWbemLastError; begin If Not VarIsEmpty(objWbemAsyncContext) then begin try Contexte:=objWbemAsyncContext.Item('SinkName',0); // IFlags tjr zéro // Si l'item n'existe pas, renvoie=wbemErrNotFound except on E:Exception do begin if (E is EOleException) or (E is EOleSysError) then begin if ExistWMIErreur(WMILastError,Self) then ShowWMIErreur('Collecteur événement onReady : Méthode Item .',WMILastError,(E as EOleException)); Memo1.Lines.Add(#13#10+'Test d''item inexistant.'); Memo1.Lines.Add(StrOriginError((E as EOleException).ErrorCode)); Memo1.Lines.Add('Erreur ['+IntToHex((E as EOleException).ErrorCode,8)+'] '+E.Message); end else Raise; //On redéclenche l'exception inconnue end; end; //Except // L'objet retourné contient une copie de l'instance de l'eventlog crée. // TargetInstance est une propriété commune aux classes : // __InstanceCreationEvent // __InstanceDeletionEvent WmiObjet:=IUnknown(objWbemObject.Properties_.Item('TargetInstance',0).Get_Value) as ISWbemObject; If Contexte.Get_Value = 'Instances' Then Memo1.Lines.Add(#13#10+'Le process '+WMIVariantToStr(WmiObjet.Properties_.Item('Name',0).Get_Value)+ ' s''est terminé.'+#13#10) else If Contexte.Get_Value = 'EventLog' then Memo1.Lines.Add(#13#10+'Un événement vient d''être ajouté au journal des événements '+ #13#10+WMIVariantToStr(WmiObjet.Properties_.Item('Message',0).Get_Value)) else begin Memo1.Lines.Add('Contexte non géré.'); Exit; end; Memo1.Lines.Add(WmiObjet.Path_.path); Memo1.Lines.Add(AdjustLineBreaks(WmiObjet.GetObjectText_(0))); end; // Else // 'Contexte' est une interface ISWbemNamedValue locale à cette procédure, Delphi // se charge de décrémenter son compteur de référence. end; |
Il est parfois nécessaire de surveiller plusieurs types d'événement pouvant être générés par une seule requête :
Code delphi : | Sélectionner tout |
1 2 3 4 | Const cstWMIEvent: Array[0..2] of String=('__InstanceCreationEvent', '__InstanceDeletionEvent', '__InstanceModificationEvent'); |
Code delphi : | Sélectionner tout |
1 2 3 4 5 | //On est informé d'une opération sur un fichier dans un directory, // les '\' sont dupliqués. Query:='Select * from __InstanceOperationEvent within 1'+ ' where TargetInstance ISA ''CIM_DataFile'''+ ' and TargetInstance.name=''c:\\temp\\test.txt'''; |
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | //Quelle requête gère-t-on ? If Contexte.Get_Value = 'Fichier' Then begin //On détermine le type de l'événement d'après son nom de classe Case AnsiIndexStr(objWbemObject.Path_.Class_,cstWMIEvent) of 0 : Memo1.Lines.Add('Création'); 1 : Memo1.Lines.Add('Suppression'); 2 : Memo1.Lines.Add('Modification'); end; //Affiche le nom du fichier, déjà connu dans cet exemple NomFichier:=WMIVariantToStr(WmiObjet.Properties_.Item('Name',0).Get_Value); Memo1.Lines.Add(#13#10+'Fichier concerné : '+WMIGetNomFichier(NomFichier)+#13#10); end |
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.