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

Langage Delphi Discussion :

La version du produit


Sujet :

Langage Delphi

  1. #1
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 388
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 388
    Points : 2 999
    Points
    2 999
    Par défaut La version du produit
    Bonjour

    Petite question d'avant week-end !
    Dans les informations de version d'un projet, on définit la version du fichier et la version du produit.
    La version du fichier, je sais la récupérer par code en décortiquant le résultat de GetFileVersionInfoSize.
    Mais la version du produit, quelle est l'instruction magique pour la retrouver ?

  2. #2
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Deux Sèvres (Poitou Charente)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Novembre 2006
    Messages : 661
    Points : 3 630
    Points
    3 630
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    Voici la fonction que j'utilise dans mes applications VCL pour récupérer les informations du projet pour les afficher par exemple dans une fenêtre "A propos" :
    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
    function GetVersionString(FileName: string; VerStr: string): string;
    var
      Size    : DWORD;
      Handle  : DWORD;
      Len     : UINT;
      Buffer  : PChar;
      Value   : PChar;
      TransNo : PLongInt;
      SFInfo  : string;
    begin
      Result := '';
      Size := GetFileVersionInfoSize(PChar(FileName), Handle);
      if Size > 0 then begin
        Buffer := AllocMem(Size);
        try
          GetFileVersionInfo(PChar(FileName), 0, Size, Buffer);
          VerQueryValue(Buffer, PChar('VarFileInfo\Translation'), Pointer(TransNo), Len);
          SFInfo := Format('%s%.4x%.4x%s%s%', ['StringFileInfo\', LoWord(TransNo^), HiWord(Transno^), '\', VerStr]);
          if VerQueryValue(Buffer, PChar(SFInfo), Pointer(Value), Len) then Result := Value;
        finally
          if Assigned(Buffer) then
            FreeMem(Buffer, Size);
        end;
      end;
    end;
    Et voici des exemples d'appel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    showmessage(GetVersionString(Application.ExeName, 'ProductVersion'));
    showmessage(GetVersionString(Application.ExeName, 'FileVersion'));
    Le premier paramètre est le fichier à analyser, le second est une chaine de caractères qui peut prendre une des valeurs indiquées dans le paragraphe Remarks de la doc Microsoft : https://docs.microsoft.com/en-us/win...verqueryvaluea
    Mon site - Mes tutoriels - GitHub - N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  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,

    en complément ou en plus, j'utilisais ce composant version D3 (pas du jeune).
    Il faudrait que je recherche ce que j'ai avec D2010 et il me semble que j'ai aussi fait un truc avec FMX
    Fichiers attachés Fichiers attachés
    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
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 388
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 388
    Points : 2 999
    Points
    2 999
    Par défaut
    Génial, merci à tous les deux !
    Je ne pensais pas qu'il fallait passer aussi par cette api.

  5. #5
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 388
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 388
    Points : 2 999
    Points
    2 999
    Par défaut
    Sans aller jusqu'au composant à installer, j'ai codé comme suit 2 fonctions et une procédure qui pourraient être utiles à d'autres.

    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
     
    unit UFileVersionOptions;
     
    interface
     
    uses Winapi.Windows, Vcl.Forms, System.SysUtils, System.Classes, System.Rtti;
     
    type
      TOptionName = (CompanyName, FileDescription, FileVersion, InternalName, LegalCopyright, LegalTradeMarks, OriginalFileName, ProgramID, ProductName,
        ProductVersion, Comments);
      TOptionNames = set of TOptionName;
     
    function GetoptionValue(FileName: string; OptionName: TOptionName): string;
     
    function GetProductVersion: string;
     
    procedure GetAllOptions(FileName: string; Resultat: TStrings);
     
    implementation
     
    function GetoptionValue(FileName: string; OptionName: TOptionName): string;
    var
      Size:    DWORD;
      Handle:  DWORD;
      Len:     UINT;
      Buffer:  PChar;
      Value:   PChar;
      TransNo: PLongInt;
      SFInfo:  string;
      Opt:     string;
    begin
      Result := '';
      Opt    := TRttiEnumerationType.GetName<TOptionName>(OptionName);
      Size   := GetFileVersionInfoSize(PChar(FileName), Handle);
      if Size > 0 then
      begin
        Buffer := AllocMem(Size);
        try
          GetFileVersionInfo(PChar(FileName), 0, Size, Buffer);
          VerQueryValue(Buffer, PChar('VarFileInfo\Translation'), Pointer(TransNo), Len);
          SFInfo := Format('%s%.4x%.4x%s%s%', ['StringFileInfo\', LoWord(TransNo^), HiWord(TransNo^), '\', Opt]);
          if VerQueryValue(Buffer, PChar(SFInfo), Pointer(Value), Len) then
            Result := Value;
        finally
          if Assigned(Buffer) then
            FreeMem(Buffer, Size);
        end;
      end;
    end;
     
    procedure GetAllOptions(FileName: string; Resultat: TStrings);
    var
      Size:    DWORD;
      Handle:  DWORD;
      Len:     UINT;
      Buffer:  PChar;
      Value:   PChar;
      TransNo: PLongInt;
      SFInfo:  string;
      Opt:     TOptionName;
      N:       string;
    begin
      if FileName.IsEmpty then
        FileName := Application.ExeName;
      if not Assigned(Resultat) then
        Resultat := TStringList.Create;
      Size       := GetFileVersionInfoSize(PChar(FileName), Handle);
      if Size > 0 then
      begin
        Buffer := AllocMem(Size);
        try
          GetFileVersionInfo(PChar(FileName), 0, Size, Buffer);
          VerQueryValue(Buffer, PChar('VarFileInfo\Translation'), Pointer(TransNo), Len);
     
          for Opt := Low(TOptionName) to High(TOptionName) do
          begin
            N      := TRttiEnumerationType.GetName<TOptionName>(Opt);
            SFInfo := Format('%s%.4x%.4x%s%s%', ['StringFileInfo\', LoWord(TransNo^), HiWord(TransNo^), '\', N]);
            if VerQueryValue(Buffer, PChar(SFInfo), Pointer(Value), Len) then
              Resultat.Add(N + '=' + Value);
          end;
     
        finally
          if Assigned(Buffer) then
            FreeMem(Buffer, Size);
        end;
      end;
    end;
     
    function GetProductVersion: string;
    var
      T: TArray<string>;
    begin
      Result := GetoptionValue(Application.ExeName, TOptionName.ProductVersion);
      T      := Result.Split(['.']);
      if Length(T) > 3 then
        Result := Format('%s.%s.%s', [T[0], T[1], T[2]]);
    end;
     
    end.

  6. #6
    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
    @Papy214

    Je me permets trois petites remarques.

    1. Juste pour la clarté du code, le nom de l'énumération devrait être au singulier (on en utilise qu'une à la fois) et réserver les pluriels pour les ensembles :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    type
      TOptionName  = (CompanyName, ...);
      TOptionNames = set of TOptionName;
    2. Les informations de version peuvent inclure des données localisées mais GetoptionValue/GetAllOptions récupéreront systématiquement la première langue.

    3. GetAllOptions n'énumère que les éléments bien connues mais d'autres entrées peuvent être présentes. Par exemple les Delphi récents ajoutent ProgramID. Pour vraiment récupérer l'ensemble (sans connaitre à l'avance ces éléments), il faudrait plonger plus profondément comme démontré ici.

  7. #7
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 388
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 388
    Points : 2 999
    Points
    2 999
    Par défaut
    Code modifié selon ta première remarque ! Merci

    Pour ta seconde remarque, je ne comprends pas trop.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    VerQueryValue(Buffer, PChar('VarFileInfo\Translation'), Pointer(TransNo), Len);
    récupère la langue définie dans les les options du projet.
    Est-ce que ça veut dire que l'on peut faire autant de configurations d'options qu'il y a de langues disponibles ?
    Si oui, je n'étais pas au courant.
    J'avais demandé à PP qu'il nous fasse un webinaire sur le sujet mais sans doute a-t-il oublié (ça s'appelle un appel du pied )

    Enfin, je ne me suis intéressé qu'aux options "standards" proposées dans l'éditeur.
    Là encore, je ne suis jamais allé aussi loin.
    Surtout que mon besoin initial n'était que la lecture de la version du produit. :-)

    Mais en tous cas, merci d'avoir éclairé ma lanterne sur tous ces éléments dont je ne soupçonnais même pas l'existence.

    Tiens, en passant, dans les valeurs de propriétés on remarque l'utilisation de $(ModuleName).
    Ca, j'ai bien compris à qui ça correspond mais est-ce qu'il y en a d'autres du même genre ?
    J'ai essayé de trouvé une référence sur le net mais sans succès.

  8. #8
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 388
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 388
    Points : 2 999
    Points
    2 999
    Par défaut
    Je viens de tester le changement de langage.
    Si je suis en Français, et que je définis un nom interne en français, puis que je passe en anglais et que je mets le même texte en anglais, puis que je reviens en français, le texte anglais reste.
    Et là, je comprends encore moins cette notion de ressource localisée :-(

    De plus, j'ajouté une info perso "Développeur" dans les options de version et ça fonctionne bien si j'utilise comme clé le mot correspondant au texte.
    Comme quoi, même à mon âge, je découvre des encore des possibilités dont je ne soupçonnais pas l'existence.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 15/12/2020, 07h26
  2. [Batch] Désinstallation selon la version du produit
    Par sys.midou dans le forum Scripts/Batch
    Réponses: 4
    Dernier message: 02/04/2018, 17h37
  3. Mettre version du produit dans le code
    Par exyacc dans le forum Langage
    Réponses: 5
    Dernier message: 19/03/2016, 08h50
  4. Réponses: 11
    Dernier message: 16/01/2015, 20h20
  5. Selection d'une version par produit
    Par LaNat dans le forum Langage SQL
    Réponses: 12
    Dernier message: 09/06/2005, 08h19

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