IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Delphi Discussion :

[D7] Base de registre - Windows 10 - 64 bits


Sujet :

Delphi

  1. #1
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut [D7] Base de registre - Windows 10 - 64 bits
    Bonjour,

    j'ai un petit soucis avec la base de registre :

    Selon la FAQ, j'essaye de lister tous les programmes installés.

    Je fais donc ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    { ============================================================================== }
    procedure TF_Princ.Btn_LogicielsClick(Sender: TObject);
    const
      REGKEYAPPS = '\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall';
    var
      reg    : TRegistry;
      List1  : TStringList;
      List2  : TStringList;
      i, n   : integer;
      j : Integer ;
     
    begin
      reg    := TRegistry.Create;
      List1  := TStringList.Create;
      List2  := TStringList.Create;
      ListBox1.Clear ;
      {Charge toutes les sous-clés}
      with reg do
      begin
        RootKey := HKEY_LOCAL_MACHINE;
        OpenKey(REGKEYAPPS, false);
        GetKeyNames(List1);
      end;
      ShowMessage('Nombre de sous-clefs : '+ IntToStr(List1.Count)) ;
      ...
    Cela me renvoie 366 sous-clefs, alors qu'avec Regedit, je n'en affiche que 60 ?

    Comment expliquer cette bizarrerie ?

    Merci

    A+
    Charly

  2. #2
    Membre expert
    Avatar de pprem
    Homme Profil pro
    MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Inscrit en
    Juin 2013
    Messages
    1 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 876
    Points : 3 611
    Points
    3 611
    Par défaut
    as-tu tenté de les afficher pour voir ce qu'il y a dans ton résultat ?

  3. #3
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 693
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 693
    Points : 13 128
    Points
    13 128
    Par défaut
    Citation Envoyé par Charly910 Voir le message
    Comment expliquer cette bizarrerie ?
    Par Regedit, ce chemin mène aux apps 64 bits alors que ton app D7 énumère les 32 bits.

    Pour lister tous les programmes installés, tu vas devoir énumérer ces deux clés en redirigeant une fois la lecture sur la clé 64 bits :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    reg := TRegistry.Create(KEY_READ);                     // apps 32 bits
    reg := TRegistry.Create(KEY_READ or KEY_WOW64_64KEY);  // apps 64 bits (KEY_WOW64_64KEY = $0100;)

  4. #4
    Membre actif
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2003
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : Distribution

    Informations forums :
    Inscription : Décembre 2003
    Messages : 167
    Points : 208
    Points
    208
    Par défaut
    Bonjour

    en fonction de la compilation 32 ou 64 bits
    lors de la lecture de la BDD sur HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall on va taper soit dans
    HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall en 32Bits
    soit dans
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall en 64Bits
    d’où la différence du nombres de clé remonté

  5. #5
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    Merci,
    je me doutait bien que c'était une histoire de 32 et 64 bits.

    avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    const
      REGKEYAPPS = '\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall';
    ...
    reg := TRegistry.Create(KEY_READ or KEY_WOW64_64KEY);
      with reg do
      begin
        RootKey := HKEY_LOCAL_MACHINE;
        OpenKey(REGKEYAPPS, false);
        GetKeyNames(List1);
      end;
    j'obtiens 60 sous-clefs ce qui parait normal par rapport à Regedit

    avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       reg := TRegistry.Create(KEY_READ);
    j'obtiens 366 sous-clefs, ce qui correspond à \SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall

    Mais même avec lze premier code, je ne retrouve pas les DisplayNames de la clef \SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

    A+
    Charly

  6. #6
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 693
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 693
    Points : 13 128
    Points
    13 128
    Par défaut
    Il ne faut pas utiliser OpenKeyReadOnly sous D7 si tu veux accéder à la clé 64 bits. Cette méthode force le flag KEY_READ uniquement, KEY_WOW64_64KEY est perdu (à noter que ce flag est préservé sur les Delphi récents). N'utilise que OpenKey.

    Lit également directement DisplayName par ReadString, énumérer les valeurs n'a aucun intérêt ici.

    Et le dernier point ; si on ouvre plusieurs clés à la suite, OpenKey doit toujours être suivi d'un CloseKey sous peine de handle leak.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    const
      REGKEYAPPS = 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall';
    var
      KeyList :TStringList;
      s       :string;
      i       :integer;
     
    begin
      with TRegistry.Create(KEY_READ or KEY_WOW64_64KEY) do
      try
        RootKey := HKEY_LOCAL_MACHINE;
     
        if OpenKey(REGKEYAPPS, FALSE) then
        begin
          KeyList := TStringList.Create;
     
          try
            GetKeyNames(KeyList);
            CloseKey;
     
            for i := 0 to KeyList.Count -1 do
              if OpenKey(REGKEYAPPS +'\' +KeyList[i], FALSE) then
              begin
                s := ReadString('DisplayName');
     
                if s <> '' then
                  Memo1.Lines.Add(KeyList[i] +' -> ' +s);
     
                CloseKey;
              end;
     
          finally
            KeyList.Free;
          end;
        end;
     
      finally
        Free;
      end;
    end;

  7. #7
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    Merci Andnotor
    En attendant j'avais bricolé ceci qui me donne satisfaction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    procedure TF_Princ.Button4Click(Sender: TObject);
    const
      REGKEYAPPS = '\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall';
    //  REGKEYAPPS2 = '\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' ;
      KEY_WOW64_64KEY = $0100;
    var
      reg    : TRegistry;
      List1  : TStringList;
      List2  : TStringList;
      i, n   : integer;
    //  j   : Integer ;
    //  Value: TRegDataInfo ;
    begin
    //   reg := TRegistry.Create(KEY_READ);                     // apps 32 bits                           ==> 366 Apps
       reg := TRegistry.Create(KEY_READ or KEY_WOW64_64KEY);  // apps 64 bits (KEY_WOW64_64KEY = $0100;)  ==> 60 Apps
      List1  := TStringList.Create;
      List2  := TStringList.Create;
      ListBox1.Clear ;
      {Charge toutes les sous-clés}
      Reg.RootKey := HKEY_LOCAL_MACHINE;
      Reg.OpenKey(REGKEYAPPS, false);
      Reg.GetKeyNames(List1);
     
      For i := 0 To List1.Count-1 Do
        Begin
          Reg.CloseKey ;
          Reg.OpenKey(REGKEYAPPS+ '\'+List1.Strings[i], false);
          List2.Clear ;
          Reg.GetValueNames(List2) ;     
     
          ListBox1.Items.add(IntToStr(i)+' - Clef : '+ List1.Strings[i]) ;
          n := List2.IndexOf('DisplayName');
          If (n >= 0)  Then
             ListBox1.Items.Add('    DisplayName : '+ reg.ReadString(List2.Strings[n]));
          n := List2.IndexOf('Publisher');
          If (n >= 0)  Then
             ListBox1.Items.Add('    Publisher   : '+ reg.ReadString(List2.Strings[n]));
          ListBox1.Items.add(' ') ;
          Reg.CloseKey ;
        End ;
      {Libération des ressources}
      List1.Free;
      List2.Free;
      reg.CloseKey;
      reg.Destroy;
    end;
    Avec ce code je retrouve le contenu de la clef Uninstall de Regedit (32 ou 64 bits ??)

    je vais tester ton code qui me parait plus simple et plus propre que le mien

    A+
    Charly

  8. #8
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    Finalement, voici la solution que j'ai adoptée (mix des 2 codes). J'ai ajouté un RadioButton pour passer du 32 au 64 bits. Le résultat s'affiche dans un TListBox :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    procedure TF_Princ.Button4Click(Sender: TObject);
    const
      REGKEYAPPS64 = '\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall';
      REGKEYAPPS32 = '\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' ;
      KEY_WOW64_64KEY = $0100;
    var
      Reg    : TRegistry;
      List1  : TStringList;
      List2  : TStringList;
      i, n   : integer;
      s      : String ;
      Valeur : String ;
      Clef   : String ;
      DateInst : TDateTime ;
    begin
      Reg := TRegistry.Create(KEY_READ or KEY_WOW64_64KEY);
      Try
        { Logiciels 64 ou 32 bits }
        If RD1.ItemIndex = 1 Then Clef := REGKEYAPPS64
                             Else Clef := REGKEYAPPS32 ;
     
        List1  := TStringList.Create;
        List2  := TStringList.Create;
     
        Try
          ListBox1.Clear ;
          {Chargement de toutes les sous-clés}
          Reg.RootKey := HKEY_LOCAL_MACHINE;
     
          If Reg.OpenKey(Clef, false) Then
            Begin
              Reg.GetKeyNames(List1);
     
             { Affichage des valeurs }
              For i := 0 To List1.Count-1 Do
                Begin
                  Reg.CloseKey ;
                  Reg.OpenKey(Clef+ '\'+List1.Strings[i], false);
                  List2.Clear ;
                  Reg.GetValueNames(List2) ;
     
                  ListBox1.Items.add(IntToStr(i)+' - Clef : '+ List1.Strings[i]) ;
     
                  Valeur := 'DisplayName' ;
                  s := Reg.ReadString(Valeur);
                  if s <> '' then ListBox1.Items.Add('    '+Valeur+' : ' +s);
                  Valeur := 'DisplayVersion' ;
                  s := Reg.ReadString(Valeur);
                  if s <> '' then ListBox1.Items.Add('    '+Valeur+' : ' +s);
                  Valeur := 'Publisher' ;
                  s := Reg.ReadString(Valeur);
                  if s <> '' then ListBox1.Items.Add('    '+Valeur+' : ' +s);
                  Valeur := 'DisplayIcon' ;
                  s := Reg.ReadString(Valeur);
                  if s <> '' then ListBox1.Items.Add('    '+Valeur+' : ' +s);
                  Valeur := 'InstallLocation' ;
                  s := Reg.ReadString(Valeur);
                  if s <> '' then ListBox1.Items.Add('    '+Valeur+' : ' +s);
                  Valeur := 'InstallDate' ;
                  s := Reg.ReadString(Valeur);
                  if s <> '' then ListBox1.Items.Add('    '+Valeur+' : ' +s);
     
                  ListBox1.Items.add(' ') ;
                  Reg.CloseKey ;
                End ;
             End ;
        Finally
          {Libération des ressources}
          List1.Free;
          List2.Free;
        End ;
      Finally
        Reg.Free;
      End ;
    end;
    Sous réserve de vérification, ce code pourrait compléter celui de la FAQ (qui ne marchait pas bien chez moi)

    Merci à tous ceux qui m'ont aidé et particulièrement AndNotOr !

    A+
    Charly

  9. #9
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 693
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 693
    Points : 13 128
    Points
    13 128
    Par défaut
    Inutile de dire que ce code ne fonctionnerait pas sur un Windows 32 bits (pas de nœud WOW6432Node).

    Le chemin doit toujours être identique et la sélection se faire par KEY_WOW64_64KEY et KEY_WOW64_32KEY.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    procedure ListInstalledApps(aList :TStrings; aApp64 :boolean);
    const
      KEY_WOW64_64KEY = $0100;
      KEY_WOW64_32KEY = $0200;
     
      REGKEYAPPS = 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall';
      Flags      : array[boolean] of word = (KEY_WOW64_32KEY, KEY_WOW64_64KEY);
      Values     : array[0..5] of string = ('DisplayName', 'DisplayVersion', 'Publisher', 'DisplayIcon', 'InstallLocation', 'InstallDate');
     
    var
      List1  : TStringList;
      i, j   : integer;
      s      : String;
     
    begin
      with TRegistry.Create(KEY_READ or Flags[aApp64]) do
      try
        RootKey := HKEY_LOCAL_MACHINE;
     
        If OpenKey(REGKEYAPPS, false) Then
        Begin
          List1 := TStringList.Create;
     
          try
            GetKeyNames(List1);
            CloseKey;
     
            for i := 0 to List1.Count -1 do
              if OpenKey(REGKEYAPPS+ '\'+List1[i], false) then
              begin
                aList.add(IntToStr(i)+' - Clef : '+ List1[i]);
     
                for j := 0 to high(Values) do
                begin
                  s := ReadString(Values[j]);
                  if s <> '' then aList.Add('    '+Values[j]+' : ' +s);
                end;
     
                aList.add('');
                CloseKey;
              end;
     
          finally
            List1.Free;
          end;
        end;
     
      Finally
        Free;
      end ;
    end;
     
    procedure TF_Princ.Button4Click(Sender: TObject);
    begin
      ListBox1.Items.Clear;
     
      ListBox1.Items.Add('********** Applications 32 bits **********');
      ListInstalledApps(ListBox1.Items, FALSE);
     
      ListBox1.Items.Add('********** Applications 64 bits **********');
      ListInstalledApps(ListBox1.Items, TRUE);
    end;

  10. #10
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    Merci AndNotOr, c'est bien plus concis comme cela.

    Mon code fonctionnait bien sur mon poste. C'est le code de la FAQ qui ne me donnait pas satisfaction.

    Est ce que l'on peut mettre ton code dans la FAQ ?

    A+
    Charly

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [WD12] base des registres Windows 7 32 bits
    Par karim15 dans le forum WinDev
    Réponses: 4
    Dernier message: 29/10/2012, 11h12
  2. [Windows]accès base de registre windows
    Par Greg01 dans le forum API standards et tierces
    Réponses: 27
    Dernier message: 05/06/2007, 15h14
  3. Réponses: 4
    Dernier message: 02/11/2005, 16h24
  4. Modifier la base de registre Windows
    Par Janitrix dans le forum API standards et tierces
    Réponses: 2
    Dernier message: 18/10/2005, 19h17
  5. Accès à la base de registre windows à distance
    Par xavame dans le forum Sécurité
    Réponses: 4
    Dernier message: 13/07/2005, 15h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo