Comment avoir un numéro de version incrémentant automatiquement (Visual Studio)? [dupliquer]

cette question a déjà une réponse ici:

je veux stocker un ensemble d'entiers qui sont incrémentés automatiquement au moment de construire:

int MajorVersion = 0;
int MinorVersion = 1;
int Revision = 92;

Quand Je compilez, il s'incrémenterait automatiquement Revision . Quand je construis le projet de configuration, il augmenterait MinorVersion (je suis D'accord avec faire cela manuellement). MajorVersion ne serait incrémenté manuellement.

alors je pourrais afficher un numéro de version dans le menu Aide / About à l'utilisateur comme:

  Version: 0.1.92

comment y parvenir?

cette question demande non seulement comment avoir un numéro de version auto-incrémentant, mais aussi comment l'utiliser dans code qui est une réponse plus complète que d'autres.

406
demandé sur esac 2009-05-06 00:28:03

9 réponses

si vous ajoutez une classe AssemblyInfo à votre projet et modifiez L'attribut AssemblyVersion pour terminer par un astérisque, par exemple:

[assembly: AssemblyVersion("2.10.*")]

Visual studio va incrémenter le nombre final pour vous selon ces règles (merci galets, j'ai eu ce complètement faux!)

pour référencer cette version en code, de sorte que vous pouvez l'afficher à l'utilisateur, vous utilisez la réflexion. Exemple,

Version version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
DateTime buildDate = new DateTime(2000, 1, 1)
                        .AddDays(version.Build).AddSeconds(version.Revision * 2);
string displayableVersion = $"{version} ({buildDate})";

deux gotchas importants que vous devez savoir

de @ashes999:

il est également intéressant de noter que si les deux AssemblyVersion et AssemblyFileVersion sont spécifiés, vous ne le verrez pas sur votre .EXE.

De @BrainSlugs83:

définir seulement le 4ème numéro pour être * peut être mauvais, car la version ne sera pas toujours incrémenter. Le 3ème numéro est le nombre de jours depuis le an 2000, et le 4ème nombre est le nombre de secondes depuis minuit (divisé par 2) [Il n'est pas aléatoire]. Donc, si vous avez construit la solution tard dans la journée un jour, et tôt dans la journée le lendemain, la dernière construction aurait un numéro de version plus tôt. Je recommande d'utiliser toujours X.Y.* au lieu de X.Y.Z.* car votre numéro de version augmentera toujours de cette façon.

534
répondu Noel Kennedy 2017-09-22 11:12:49

vous pouvez utiliser le T4 templating mechanism dans Visual Studio pour générer le code source requis à partir d'un simple fichier texte :

je voulais configurer la génération d'information de version pour certains .NET projet. Il a été un long temps depuis que j'ai étudié disponible options, donc j'ai cherché partout en espérant trouver un moyen simple de faire ce. Ce que j'ai trouvé n'avait pas l'air très encourageant: les gens écrivent Visual Studio compléments et personnalisé tâches MsBuild juste pour obtenir un nombre entier (d'accord, peut-être deux). C'était trop pour un petit projet personnel.

l'inspiration est venue d'une des discussions StackOverflow où quelqu'un a suggéré que les modèles T4 pourraient faire l'affaire. Et bien sûr ils peuvent. La solution nécessite un minimum d'effort et pas de studio visuel ou la personnalisation du processus de construction. Ici ce qui doit être fait:

  1. créer un fichier avec l'extension ".tt" et y placer modèle T4 qui va générer AssemblyVersion et AssemblyFileVersion attributs:
<#@ template language="C#" #>
// 
// This code was generated by a tool. Any changes made manually will be lost
// the next time this code is regenerated.
// 

using System.Reflection;

[assembly: AssemblyVersion("1.0.1.<#= this.RevisionNumber #>")]
[assembly: AssemblyFileVersion("1.0.1.<#= this.RevisionNumber #>")]
<#+
    int RevisionNumber = (int)(DateTime.UtcNow - new DateTime(2010,1,1)).TotalDays;
#>

vous devrez décider de l'algorithme de génération du numéro de version. Pour moi c'était suffisant pour générer automatiquement un numéro de révision qui est mis à le nombre de jours depuis le 1er janvier 2010. Comme vous pouvez le voir, le la règle de génération de version est écrite en C # simple, de sorte que vous pouvez facilement l'ajuster à vos besoins.

  1. Le fichier ci-dessus doit être placé dans l'un des projets. J'ai créé un nouveau projet avec juste ce fichier unique pour faire la gestion de version technique claire. Quand je construis ce projet (en fait je n'ai même pas besoin pour le construire: sauvegarder le fichier est suffisant pour déclencher un studio visuel action), le C# suivant est généré:
// 
// This code was generated by a tool. Any changes made manually will be lost
// the next time this code is regenerated.
// 

using System.Reflection;

[assembly: AssemblyVersion("1.0.1.113")]
[assembly: AssemblyFileVersion("1.0.1.113")]

Oui, aujourd'hui c'est 113 jours depuis le 1er janvier 2010. Demain, le le numéro de révision changera.

  1. la prochaine étape consiste à supprimer les attributs AssemblyVersion et AssemblyFileVersion de AssemblyInfo.cs des fichiers dans tous les projets qui devraient partagez la même information de version générée automatiquement. Choisissez plutôt "Ajouter" élément existant" pour chaque projet, naviguez vers le dossier avec T4 le fichier de modèle, sélectionnez correspondant ".cs " fichier et l'ajouter comme un lien. Que va faire!

ce que j'aime dans cette approche, c'est qu'elle est légère (aucune MsBuild tasks), et l'information de version générée automatiquement n'est pas ajoutée contrôle à la source. Et bien sûr en utilisant C# pour la génération de version l'algorithme s'ouvre pour les algorithmes de toute complexité.

150
répondu Matthieu 2016-01-19 12:10:16

c'est ma mise en œuvre de la suggestion T4... Cela incrémentera le numéro de compilation à chaque fois que vous construisez le projet indépendamment de la configuration choisie (c.-à-d. débogage|publication), et cela augmentera le numéro de révision à chaque fois que vous construisez une version. Vous pouvez continuer à mettre à jour les numéros de version major et minor à l'aide de L'Application ➤ information sur l'assemblage...

AssemblyInfo.cs fichier, et utiliser regex pour trouver l'information AssemblyVersion , puis incrémenter la révision et construire des nombres basés sur l'entrée de TextTransform.exe .

  1. supprimez votre fichier AssemblyInfo.cs existant.
  2. créer un fichier AssemblyInfo.tt à sa place. Visual Studio devrait créer AssemblyInfo.cs et le grouper avec le fichier T4 après avoir sauvegardé le fichier T4.

    <#@ template debug="true" hostspecific="true" language="C#" #>
    <#@ output extension=".cs" #>
    <#@ import namespace="System.IO" #>
    <#@ import namespace="System.Text.RegularExpressions" #>
    <#
        string output = File.ReadAllText(this.Host.ResolvePath("AssemblyInfo.cs"));
        Regex pattern = new Regex("AssemblyVersion\(\"(?<major>\d+)\.(?<minor>\d+)\.(?<revision>\d+)\.(?<build>\d+)\"\)");
        MatchCollection matches = pattern.Matches(output);
        if( matches.Count == 1 )
        {
            major = Convert.ToInt32(matches[0].Groups["major"].Value);
            minor = Convert.ToInt32(matches[0].Groups["minor"].Value);
            build = Convert.ToInt32(matches[0].Groups["build"].Value) + 1;
            revision = Convert.ToInt32(matches[0].Groups["revision"].Value);
            if( this.Host.ResolveParameterValue("-","-","BuildConfiguration") == "Release" )
                revision++;
        }
    #>
    
    using System.Reflection;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using System.Resources;
    
    // General Information
    [assembly: AssemblyTitle("Insert title here")]
    [assembly: AssemblyDescription("Insert description here")]
    [assembly: AssemblyConfiguration("")]
    [assembly: AssemblyCompany("Insert company here")]
    [assembly: AssemblyProduct("Insert product here")]
    [assembly: AssemblyCopyright("Insert copyright here")]
    [assembly: AssemblyTrademark("Insert trademark here")]
    [assembly: AssemblyCulture("")]
    
    // Version informationr(
    [assembly: AssemblyVersion("<#= this.major #>.<#= this.minor #>.<#= this.revision #>.<#= this.build #>")]
    [assembly: AssemblyFileVersion("<#= this.major #>.<#= this.minor #>.<#= this.revision #>.<#= this.build #>")]
    [assembly: NeutralResourcesLanguageAttribute( "en-US" )]
    
    <#+
        int major = 1;
        int minor = 0;
        int revision = 0;
        int build = 0;
    #>
    
  3. ajouter ceci à votre événement pré-construction:

    "%CommonProgramFiles(x86)%\microsoft shared\TextTemplating$(VisualStudioVersion)\TextTransform.exe" -a !!BuildConfiguration!$(Configuration) "$(ProjectDir)Properties\AssemblyInfo.tt"
    
37
répondu Drew Chapin 2018-02-14 15:45:21

si vous mettez un astérisque pour construire et réviser visual studio utilise le nombre de jours depuis Janvier. 1er 2000 le numéro de build, et le nombre de secondes depuis minuit divisé par 2 la révision.

une solution d'économie de vie beaucoup mieux est http://autobuildversion.codeplex.com /

il fonctionne comme un charme et il est très flexible.

30
répondu gideon 2012-01-05 04:23:30

Voici la citation sur AssemblyInfo.cs from MSDN :

, Vous pouvez spécifier toutes les valeurs ou vous peut accepter le numéro de construction par défaut, numéro de révision, ou les deux en utilisant un astérisque ( ). Exemple, [assemblage: AssemblyVersion ("2.3.25.1")] indique 2 comme version principale, 3 comme la version mineure, 25 comme le construire nombre, et 1 comme numéro de révision. Un numéro de version tel que comme [assemblage: AssemblyVersion ("1.2. ")] spécifie 1 comme version principale, 2 comme la version mineure, et accepte le les numéros de compilation et de révision par défaut. Un numéro de version tel que [assemblage: AssemblyVersion ("1.2.15.*")] spécifie 1 comme version principale, 2 comme la version mineure, 15 comme le construire nombre, et accepte la valeur par défaut numéro de révision. La construction par défaut nombre augmente tous les jours. Défaut le numéro de révision est aléatoire

Cela dit effectivement, si vous mettez un 1.1.* dans les informations d'assemblage, seul le nombre de build va s'autodétruire, et cela n'arrivera pas après chaque build, mais quotidiennement. Le numéro de révision changera à chaque compilation, mais de manière aléatoire, plutôt que de façon incrémentielle.

C'est probablement suffisant pour la plupart des cas d'utilisation. Si ce n'est pas ce que vous cherchez, vous êtes coincé avec l'écriture d'un script qui va auto-ordonner la version # sur l'étape de pré-construction

24
répondu galets 2009-05-05 20:53:07

Utiliser AssemblyInfo.cs

créer le fichier dans App_Code: et remplir ce qui suit ou utiliser Google pour d'autres possibilités d'attribut/propriété.

AssemblyInfo.cs

using System.Reflection;

[assembly: AssemblyDescription("Very useful stuff here.")]
[assembly: AssemblyCompany("companyname")]
[assembly: AssemblyCopyright("Copyright © me 2009")]
[assembly: AssemblyProduct("NeatProduct")]
[assembly: AssemblyVersion("1.1.*")]

AssemblyVersion étant la partie que vous recherchez vraiment.

alors si vous travaillez sur un site Web, dans n'importe quelle page aspx, ou contrôle, vous pouvez ajouter dans la balise ce qui suit:

CompilerOptions="<folderpath>\App_Code\AssemblyInfo.cs"

(remplaçant folderpath par une variable appropriée bien sûr).

Je ne crois pas que vous ayez besoin d'ajouter des options de compilateur de quelque manière que ce soit pour d'autres classes; tous ceux qui sont dans L'App_Code devraient recevoir les informations de version lorsqu'ils sont compilés.

Espère que ça aide.

14
répondu Micah Smith 2009-05-05 21:03:56

vous pouvez essayer d'utiliser UpdateVersion par Matt Griffith . C'est assez vieux maintenant, mais fonctionne bien. Pour l'utiliser, vous avez simplement besoin de configurer un événement pré-construction qui pointe sur votre AssemblyInfo.cs file, et l'application mettra à jour les numéros de version en conséquence, selon les arguments de ligne de commande.

comme l'application est open-source, j'ai aussi créé une version pour incrémenter le numéro de version en utilisant le format (majeur version.)(Version mineure).([année][Jour de l'année]).(incrément) . Plus d'informations à ce sujet et le code révisé est disponible sur mon blog, Assembly Version Numbers and .NET .

mise à jour: j'ai mis le code de ma version modifiée de L'application UpdateVersion sur GitHub: https://github.com/munr/UpdateVersion

10
répondu Mun 2013-09-08 19:15:50
  • "151940920 des Étoiles" dans la version (comme "2.10.3.*") - c'est simple, mais les nombres sont trop grands

  • AutoBuildVersion - ça a l'air génial mais ça ne marche pas sur ma VS2010.

  • le script de @DrewChapin fonctionne, mais je ne peux pas dans mon studio mettre différents modes pour déboguer l'événement de pré-construction et L'événement de pré-construction de sortie.

donc j'ai changé le script a bit... commamd:

"%CommonProgramFiles(x86)%\microsoft shared\TextTemplating.0\TextTransform.exe" -a !!$(ConfigurationName)!1 "$(ProjectDir)Properties\AssemblyInfo.tt"

et le script (cela fonctionne à l' "Debug" et "Release" configurations):

<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="System.Windows.Forms" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<#
    int incRevision = 1;
    int incBuild = 1;

    try { incRevision = Convert.ToInt32(this.Host.ResolveParameterValue("","","Debug"));} catch( Exception ) { incBuild=0; }
    try { incBuild = Convert.ToInt32(this.Host.ResolveParameterValue("","","Release")); } catch( Exception ) { incRevision=0; }
    try {
        string currentDirectory = Path.GetDirectoryName(Host.TemplateFile);
        string assemblyInfo = File.ReadAllText(Path.Combine(currentDirectory,"AssemblyInfo.cs"));
        Regex pattern = new Regex("AssemblyVersion\(\"\d+\.\d+\.(?<revision>\d+)\.(?<build>\d+)\"\)");
        MatchCollection matches = pattern.Matches(assemblyInfo);
        revision = Convert.ToInt32(matches[0].Groups["revision"].Value) + incRevision;
        build = Convert.ToInt32(matches[0].Groups["build"].Value) + incBuild;
    }
    catch( Exception ) { }
#>
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Game engine. Keys: F2 (Debug trace), F4 (Fullscreen), Shift+Arrows (Move view). ")]
[assembly: AssemblyProduct("Game engine")]
[assembly: AssemblyDescription("My engine for game")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyCopyright("Copyright © Name 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components.  If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type. Only Windows
// assemblies support COM.
[assembly: ComVisible(false)]

// On Windows, the following GUID is for the ID of the typelib if this
// project is exposed to COM. On other platforms, it unique identifies the
// title storage container when deploying this assembly to the device.
[assembly: Guid("00000000-0000-0000-0000-000000000000")]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version
//      Build Number
//      Revision
//
[assembly: AssemblyVersion("0.1.<#= this.revision #>.<#= this.build #>")]
[assembly: AssemblyFileVersion("0.1.<#= this.revision #>.<#= this.build #>")]

<#+
    int revision = 0;
    int build = 0;
#>
10
répondu Dmi7ry 2018-01-26 04:51:31

vous pouvez faire plus avancé versioning en utilisant des scripts de construction tels que construire Versioning

2
répondu Raymond 2009-12-23 19:12:29