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

API, COM et SDKs Delphi Discussion :

Extraire les informations de version, VerQueryValue, avoir une liste des informations


Sujet :

API, COM et SDKs Delphi

  1. #1
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 043
    Points : 40 957
    Points
    40 957
    Billets dans le blog
    62
    Par défaut Extraire les informations de version, VerQueryValue, avoir une liste des informations
    Bonjour,

    Je cherche à extraire les informations de versions de programmes (ou autres) et ce via GetFileVersionInfoSize,GetFileVersionInfo puis VerQueryValue.
    Si pour ce qui s'agit des informations prédéfinies
    Comments,InternalName,ProductName,CompanyName,LegalCopyright,ProductVersion,FileDescription,LegalTrademarks,PrivateBuild,FileVersion,OriginalFilename,SpecialBuild
    cela ne me pose aucun problème mais, comment sait-on s'il y a d'autres informations disponibles ? je sais que c'est possible voir le site delphidabler.com je pourrais d'ailleurs utiliser ces programmes mais j'aimerais bien avoir une solution de mon cru
    Je n'ai pas encore fouillé à fond, mais toute piste est la bienvenue
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 694
    Points : 13 130
    Points
    13 130
    Par défaut
    En général, un pointeur non typé passé à GetFileVersionInfo suffit si on connait le nom de la donnée à récupérer (CompanyName, FileDescription, etc.)
    il faut par contre connaitre précisément la structure pour pouvoir énumérer toutes les données et donc passer par un pointeur de type VS_VERSIONINFO.

    A noter que Microsoft ne fournit qu'une description des structures nécessaires, elles ne sont déclarées dans aucun header.

    This structure is not a true C-language structure because it contains variable-length members. This structure was created solely to depict the organization of data in a version resource and does not appear in any of the header files shipped with the Windows Software Development Kit (SDK).
    Je me suis amusé à implémenter cela (ce code ne gère que le bloc StringFileInfo, pas VarFileInfo).

    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
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    unit FileVersionInfo;
     
    interface
     
    uses Windows, Types, SysUtils;
     
    function GetFileVersionInfoList(const aFileName :TFileName) :TStringDynArray;
     
    implementation
     
    // - Ces structures ne sont que des prototypes, leurs tailles sont variables et dépendent des Children
    //   (TVersionInfo, TStringFileInfo, TStringTable) ou de la longueur des chaînes (TString).
     
    // - Les Children et Value sont toujours alignés sur 32 bits. Les "Padding" serviraient à assurer cet
    //   alignement si la somme des tailles des données précédentes n'étaient pas multiple de 4 octets.
    //   Il n'y a ici aucune structure le demandant mais Padding est laissé en commentaire pour info.
     
    // - Les Children sont déclarés en "array[0..0] of" uniquement pour rappeler qu'il s'agit de tableaux mais
    //   il est impossible d'atteindre un élément par son indice puisque les Children sont de taille variable.
    //   On récupère la position du Child suivant en ajoutant au pointeur la taille du Child courant (plus le
    //   complément pour un alignement sur 32 bits).
     
    type
      //https://msdn.microsoft.com/en-us/library/windows/desktop/ms646987(v=vs.85).aspx
      PString = ^TString;
      TString = record
        wLength      :word;
        wValueLength :word;
        wType        :word;
        szKey        :array[0..0] of widechar;                         //La clé, chaîne de longeur variable à #0 terminal.
        //Padding    :array[0..0] of word;
        //Value      :array[0..0] of widechar;                         //szKey étant de taille variable, déclarer Value est parfaitement inutile.
                                                                       //On trouve sa position (offset) en soustrayant sa taille (wValueLength) à
                                                                       //la taille de la structure (wLength).
                                                                       //La valeur est une chaîne à #0 terminal.
        function     Key: string;
        function     Value: string;
      end;
     
      //https://msdn.microsoft.com/en-us/library/windows/desktop/ms646992(v=vs.85).aspx
      PStringTable = ^TStringTable;
      TStringTable = record
        wLength      :word;
        wValueLength :word;
        wType        :word;
        szKey        :array[0..8] of widechar;                         //Chaîne à #0 terminal représentant la langue et le codepage au format héxa.
        //Padding    :array[0..0] of word;
        Children     :array[0..0] of TString;                          //Liste des paires clé=valeur
     
        function     First(var P: PString): boolean;
        function     Next(var P: PString): boolean;
      end;
     
      //https://msdn.microsoft.com/en-us/library/windows/desktop/ms646989(v=vs.85).aspx
      PStringFileInfo = ^TStringFileInfo;
      TStringFileInfo = record
        wLength      :word;
        wValueLength :word;
        wType        :word;
        szKey        :array[0..Length('StringFileInfo')] of widechar;  //Vaut toujours 'StringFileInfo'#0
        //Padding    :array[0..0] of word;
        Children     :array[0..0] of TStringTable;                     //Liste des tables par langue/codepage
     
        function     First(var P: PStringTable): boolean;
        function     Next(var P: PStringTable): boolean;
      end;
     
      //https://msdn.microsoft.com/en-us/library/windows/desktop/ms647001(v=vs.85).aspx
      PVersionInfo = ^TVersionInfo;
      TVersionInfo = record
        wLength      :word;
        wValueLength :word;
        wType        :word;
        szKey        :array[0..Length('VS_VERSION_INFO')] of widechar; //Vaut toujours 'VS_VERSION_INFO'#0
        //Padding1   :array[0..0] of word;
        Value        :TVSFixedFileInfo;                                //Information de version non localisée
        //Padding2   :array[0..0] of word;
        Children     :array[0..0] of TStringFileInfo;                  //StringFileInfo et/ou VarFileInfo
     
        function     Get(var P: PStringFileInfo): boolean;
      end;
     
    { TVersionInfo }
     
    function TVersionInfo.Get(var P: PStringFileInfo): boolean;
    begin
      P := @Children;
      Result := SameText(P.szKey, 'StringFileInfo');
    end;
     
    { TStringFileInfo }
     
    function TStringFileInfo.First(var P: PStringTable): boolean;
    begin
      P := @Children;
      Result := integer(P) < integer(@Self) +wLength;
    end;
     
    function TStringFileInfo.Next(var P: PStringTable): boolean;
    begin
      //Les données sont alignées sur 32 bits
      inc(PByte(P), P.wLength +P.wLength mod SizeOf(dword));
      Result := integer(P) < integer(@Self) +wLength;
    end;
     
    { TStringTable }
     
    function TStringTable.First(var P: PString): boolean;
    begin
      P := @Children;
      Result := integer(P) < integer(@Self) +wLength;
    end;
     
    function TStringTable.Next(var P: PString): boolean;
    begin
      //Les données sont alignées sur 32 bits
      inc(PByte(P), P.wLength +P.wLength mod SizeOf(dword));
      Result := integer(P) < integer(@Self) +wLength;
    end;
     
    { TString }
     
    function TString.Key: string;
    begin
      Result := PChar(@szKey);
    end;
     
    function TString.Value: string;
    var
      P :PByte;
    begin
      //szKey étant de longueur variable, il faut
      //localiser Value depuis la fin de la structure.
      P := @Self;
      inc(P, wLength -wValueLength *SizeOf(word));
      Result := PChar(P);
    end;
     
    //=============================================================================
     
    function GetFileVersionInfoList(const aFileName :TFileName) :TStringDynArray;
    var
      Block          :PVersionInfo;
      Size           :cardinal;
      Dummy          :cardinal;
      StringFileInfo :PStringFileInfo;
      StringTable    :PStringTable;
      S              :PString;
     
      //---------------------------------------------
      procedure Add(aIdent :integer; aText :string);
      begin
        SetLength(Result, Length(Result) +1);
        Result[High(Result)] := StringOfChar(#9, aIdent) +aText;
      end;
      //---------------------------------------------
     
    begin
      SetLength(Result, 0);
     
      Size := GetFileVersionInfoSize(PChar(aFileName), Dummy);
     
      if Size > 0 then
      begin
        GetMem(Block, Size);
     
        if GetFileVersionInfo(PChar(aFileName), 0, Size, Block) then
        begin
          if Block.Get(StringFileInfo) then
          begin
            Add(0, 'StringFileInfo');
     
            if StringFileInfo.First(StringTable) then
            repeat
              Add(1, StringTable.szKey);
     
              if StringTable.First(S) then
              repeat
                Add(2, S.Key +'=' + S.Value);
              until not StringTable.Next(S);
     
            until not StringFileInfo.Next(StringTable);
     
          end;
        end;
      end;
    end;
     
    end.

  3. #3
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 043
    Points : 40 957
    Points
    40 957
    Billets dans le blog
    62
    Par défaut
    Bonjour,
    Citation Envoyé par Andnotor Voir le message
    Je me suis amusé à implémenter cela.
    Chapeau bas, pour tes "amusements". Je n'avais pas eu le temps de m'y mettre Samedi et Vendredi j'avais juste un peu creusé dans les sources citées (beaucoup plus complexe que ton code). J'ai juste désactivé ton indentation pour obtenir ce qu'il me fallait. C'est pas une mousse que tu mérites mais un fût
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 043
    Points : 40 957
    Points
    40 957
    Billets dans le blog
    62
    Par défaut Petite correction à apporter
    Bonjour,

    Sur un projet j'avais une fuite de mémoire je me suis aperçu qu'elle venait d'un petit oubli de AndNotOr dans son unité.

    la variable Block ligne 143 a de la mémoire allouée ligne 165 GetMem(Block, Size); toutefois celle-ci n'est pas libérée
    je suggère donc de rajouter une instruction entre les lignes 185 et 186 (fin du bloc if Size>0 then)
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

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

Discussions similaires

  1. Avoir la liste des commandes saisies sur une période
    Par mortal dans le forum Administration système
    Réponses: 12
    Dernier message: 23/12/2015, 15h32
  2. Réponses: 7
    Dernier message: 21/04/2005, 15h55
  3. [IDE][VS.NET 2003] Y a-t-il une liste des racourcis ?
    Par 404Found dans le forum Contribuez
    Réponses: 2
    Dernier message: 22/06/2004, 20h20
  4. Réponses: 3
    Dernier message: 09/01/2004, 14h37

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