FAQ DelphiConsultez toutes les FAQ

Nombre d'auteurs : 123, nombre de questions : 923, dernière mise à jour : 29 avril 2020  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.

Commentez


SommaireSystèmeWMIFichiers et répertoires (3)
précédent sommaire suivant
 

On utilise à cette fin un collecteur de donnée asynchrone. La requête d'événement se construit de la manière suivante :

  • l'événement cible est '__InstanceCreationEvent'
  • la classe concernée est une classe d'association du type CIM_DirectoryContainsFile
  • la propriété concernée, de la classe CIM_Directory, est TargetInstance.GroupComponent
  • qui doit être égale au nom du répertoire à surveiller, ici : C:\Temp (les '\' sont dupliqués)
  • on ne récupère que la propriété WIN32_Directory.Name, classe héritant de la classe CIM_Directory.

Code delphi : Sélectionner tout
1
2
3
4
// Sont concernées les instances de la classe CIM_DirectoryContainsFile (Directory) 
// On est informé lors de la création de fichier dans un répertoire. 
Query:='Select * from __InstanceCreationEvent within 1 where TargetInstance '+ 
  'isa ''CIM_DirectoryContainsFile'' and TargetInstance.GroupComponent=''WIN32_Directory.name="c:\\\\temp"''';
Dans le gestionnaire d'événements onReady du collecteur de données, on manipule l'instance de la manière suivante :
Code delphi : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
... 
      WmiObjet:=IUnknown(objWbemObject.Properties_.Item('TargetInstance',0).Get_Value) as ISWbemObject; 
  
      If Contexte.Get_Value = 'Fichier' 
       Then 
        begin 
          // On récupère une propriété qui est plus ou moins une issue d'une association : 
          // The CIM_DirectoryContainsFile class represents an association between 
          // a directory and files contained within that directory. 
         NomFichier:=WMIVariantToStr(WmiObjet.Properties_.Item('PartComponent',0).Get_Value); 
          //Le nom de fichier a un syntaxe particulière 
         Memo1.Lines.Add(#13#10+'Le Fichier crée : '+WMIGetNomFichier(NomFichier)+#13#10); 
        end 
...

Mis à jour le 15 janvier 2014 Laurent Dardenne Pedro

La marche à suivre reste identique à celle indiquée dans Comment surveiller la création de fichiers dans un répertoire ? à la différence que la requête WQL porte sur un autre type d'instance :

Code delphi : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
  // Recherche tous les événements de la classe __InstanceOperationEvent liés à un fichier en particulier 
  // WMI effectue le polling chaque seconde. 
  //( temps de polling recommandé 300 secondes, si aprés le démarrage du polling 
  // un fichier est créé puis supprimé, pendant ce laps de temps, l'événement n'est pas 'vu' ) 
  // sont concernées les instances de la classe CIM_DataFile (Fichier) 
  // 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''';
Le code de gestion des événements, quant à lui, porte sur les instances de :
  • __InstanceCreationEvent
  • __InstanceDeletionEvent
  • __InstanceModificationEvent.

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
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é 
  
Const cstWMIEvent: Array[0..2] of String=('__InstanceCreationEvent','__InstanceDeletionEvent','__InstanceModificationEvent'); 
  
var WmiObjet: ISWbemObject; 
    WMIContext : TSWbemNamedValueSet; 
    Contexte : ISWbemNamedValue; 
    WMILastError: TSWbemLastError; 
    NomFichier : String; 
    ClassseEvenement : String; 
begin 
Try 
  If Not VarIsEmpty(objWbemAsyncContext) 
   then 
    begin 
       // On utilise un TOleServer que l'on connecte à l'interface reçue en paramètre 
      WMIContext:=TSWbemNamedValueSet.Create(Self); 
      With WMIContext do 
       begin 
        AutoConnect:=False; 
        ConnectKind :=ckAttachToInterface; 
        ConnectTo(IUnknown(objWbemAsyncContext) as ISWbemNamedValueSet); 
       end; 
     try 
       //retrouve la collection initialisée au démarrage de l'application 
      Contexte:= WMIContext.Item('SinkName',0); // IFlags toujours zéro 
       // Si l'item n'existe pas, renvoi=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; 
       end; 
     end; 
  
       // L'objet retourné est un événement. 
       // Sa propriété TargetInstance, commune aux 3 classes, contient une copie de l'instance du fichier concerné.  : 
      WmiObjet:=IUnknown(objWbemObject.Properties_.Item('TargetInstance',0).Get_Value) as ISWbemObject; 
  
       //Quelle requête gère-t-on ? 
      If Contexte.Get_Value = 'Fichier' 
       Then 
        begin 
           //On détermine le type de l'évent 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 
       else 
         begin 
          Memo1.Lines.Add('Contexte non géré.'); 
          Exit; 
         end; 
       //Affiche le détail de 'l'objet fichier' 
      Memo1.Lines.Add(WmiObjet.Path_.path); 
      Memo1.Lines.Add(AdjustLineBreaks(WmiObjet.GetObjectText_(0))); 
    end; 
  // Else 
  
 Finally 
  // 'Contexte' est une interface ISWbemNamedValue locale à cette procédure, Delphi 
  // se charge de décrémenter son compteur de référence. 
  FreeAndNil(WMIContext); 
 end; 
end;
Le code précédent et suivant ce traitement est identique à celui indiqué dans la QR Comment collecter les informations de plusieurs requêtes d'événements asynchrones ?.

Mis à jour le 15 janvier 2014 Laurent Dardenne

WMI permet aussi de surveiller l'activité sur la registry, la marche à suivre reste identique à celle indiquée dans Comment surveiller les opérations effectuées sur un fichier ?

À la différence que la requête WQL porte sur un type d'instance spécifique et que le référentiel à interroger est root\default et non plus root\CIMV2

Voici les événements disponibles :

  • RegistryEvent : Classe abstraite dont les autres classes d'événements sont dérivées.
  • RegistryKeyChangeEvent : Représente les changements d'une clé spécifique.
  • RegistryTreeChangeEvent : Représente les changements d'une clé spécifique ou de ses sous-clés.
  • RegistryValueChangeEvent : Représente les changements de la valeur d'une clé spécifique.

Il est possible de surveiller toutes les modifications faites sur la valeur d'une clé particulière :
Code delphi : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
//Classe de base RegistryEvent 
  // Erreur si on ne se connecte pas dans le bon espace de nom. 
  // Erreur si on ne précise pas toutes les propriétés dans la requête WQL. 
  // Attention on ne récupère pas le nouveau contenu de la clé modifiée 
  // 
  // On est informé d'une opération sur la base de registre. 
  //Pour toutes les modifications faites sur la valeur d'une clé particuliére 
  //  HKEY_LOCAL_MACHINE\SOFTWARE\Developpez\Delphi\Sujet. 
  Query:= 'SELECT * FROM RegistryValueChangeEvent'+ 
          ' WHERE Hive=''HKEY_LOCAL_MACHINE'' AND'+ 
          ' KeyPath=''SOFTWARE\\Developpez\\Delphi'' AND'+ 
          'ValueName=''Sujet''';
Il reste possible de surveiller aussi
  • Toutes les modifications faites sur une clé et ces sous-clés :
    Code delphi : Sélectionner tout
    1
    2
    3
    4
    //  HKEY_LOCAL_MACHINE\SOFTWARE\Developpez\Delphi 
      Query:= 'SELECT * FROM RegistryKeyChangeEvent'+ 
              ' WHERE Hive=''HKEY_LOCAL_MACHINE'' AND'+ 
    		  ' KeyPath=''SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion'';
  • Toutes les modifications faites sur une portion d'une arborescence/ruche
    Code delphi : Sélectionner tout
    1
    2
    //  HKEY_LOCAL_MACHINE 
        Query:='SELECT * FROM RegistryTreeChangeEvent WHERE Hive=''HKEY_LOCAL_MACHINE'' AND RootPath=''';

Le code de gestion des événements, quant à lui, porte sur les mêmes types d'instances qui sont communes à presque toutes les classes d'événement :
  • __InstanceCreationEvent,
  • __InstanceDeletionEvent et
  • __InstanceModificationEvent.

Mis à jour le 15 janvier 2014 Laurent Dardenne

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 ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les 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 © 2020 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.