Comment avoir un numéro de version auto-incrémenté (Visual Studio)?

Je veux stocker un ensemble d’entiers qui sont automatiquement incrémentés au moment de la construction:

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

Lorsque je comstack, il incrémenterait automatiquement la Revision . Lorsque je construis le projet d’installation, cela incrémenterait MinorVersion (je suis d’accord pour le faire manuellement). MajorVersion ne sera incrémenté que manuellement.

Ensuite, j’ai pu afficher un numéro de version dans le menu Aide / A propos de l’utilisateur en tant que:

   Version: 0.1.92

Comment cela peut il etre accompli?

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

Si vous ajoutez une classe AssemblyInfo à votre projet et modifiez l’atsortingbut AssemblyVersion pour qu’il se termine par un astérisque, par exemple:

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

Visual Studio va incrémenter le nombre final selon ces règles (merci les galets, je me suis complètement trompé!)

Pour référencer cette version dans le code, afin que vous puissiez l’afficher à l’utilisateur, vous utilisez la reflection. Par exemple,

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

Deux pièges importants à connaître

De @ ashes999:

Il est également intéressant de noter que si AssemblyVersion et AssemblyFileVersion sont spécifiés, vous ne verrez pas cela sur votre fichier .exe.

De @ BrainSlugs83:

Ne définir que le 4ème numéro comme étant * peut être mauvais, car la version n’incrémente pas toujours. Le 3ème nombre est le nombre de jours écoulés depuis l’an 2000, et le 4ème nombre correspond au nombre de secondes écastings depuis minuit (divisé par 2) [IL N’EST PAS RANDOM]. Donc, si vous construisiez la solution tard dans la journée, un jour et au début de la journée, le plus récent aurait un numéro de version antérieur. Je recommande de toujours utiliser XY* au lieu de XYZ* car votre numéro de version augmentera TOUJOURS de cette façon.

Vous pouvez utiliser le mécanisme de modélisation T4 dans Visual Studio pour générer le code source requirejs à partir d’un fichier texte simple :

Je voulais configurer la génération d’informations de version pour certains projets .NET. Cela fait longtemps que je n’ai pas étudié les options disponibles, alors j’ai cherché autour de moi en espérant trouver un moyen simple de le faire. Ce que j’ai trouvé n’a pas l’air très encourageant: les gens écrivent des compléments Visual Studio et des tâches MsBuild personnalisées pour obtenir un nombre entier (d’accord, peut-être deux). Cela a semblé exagéré pour un petit projet personnel.

L’inspiration est venue d’une des discussions de 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 effort minimal et aucune personnalisation de Visual Studio ou de processus de génération. Voici ce qu’il faut faire:

  1. Créez un fichier avec l’extension “.tt” et placez-y un modèle T4 qui générera les atsortingbuts AssemblyVersion et AssemblyFileVersion:
 <#@ 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, il suffisait de générer automatiquement un numéro de révision défini sur le nombre de jours écoulés depuis le 1er janvier 2010. Comme vous pouvez le constater, la règle de génération de version est écrite en C #, ce qui vous permet de l’ajuster facilement à vos besoins. .

  1. Le fichier ci-dessus doit être placé dans l’un des projets. J’ai créé un nouveau projet avec ce seul fichier pour rendre la technique de gestion des versions plus claire. Lorsque je construis ce projet (en fait je n’ai même pas besoin de le construire: sauvegarder le fichier est suffisant pour déclencher une action Visual Studio), 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, il y a 113 jours depuis le 1er janvier 2010. Demain, le numéro de révision changera.

  1. L’étape suivante consiste à supprimer les atsortingbuts AssemblyVersion et AssemblyFileVersion des fichiers AssemblyInfo.cs dans tous les projets devant partager les mêmes informations de version générées automatiquement. Choisissez plutôt «Ajouter un élément existant» pour chaque projet, accédez au dossier contenant le fichier de modèle T4, sélectionnez le fichier «.cs» correspondant et ajoutez-le en tant que lien. Ça va faire!

Ce que j’aime dans cette approche, c’est qu’elle est légère (pas de tâches MsBuild personnalisées) et que les informations de version générées automatiquement ne sont pas ajoutées au contrôle de code source. Et bien sûr, l’utilisation de C # pour l’algorithme de génération de version s’ouvre pour des algorithmes de toute complexité.

Ceci est mon implémentation de la suggestion T4 … Cela incrémentera le numéro de compilation chaque fois que vous construirez le projet indépendamment de la configuration sélectionnée (par exemple, Debug | Release), et incrémentera le numéro de révision chaque fois que vous réaliserez une version. Vous pouvez continuer à mettre à jour les numéros de version majeurs et mineurs via l’ application Information Informations d’assemblage …

Pour expliquer plus en détail, cela lira le fichier AssemblyInfo.cs existant et utilisera regex pour rechercher les informations AssemblyVersion , puis pour incrémenter la révision et générer des nombres en fonction des entrées de TextTransform.exe .

  1. Supprimez votre fichier AssemblyInfo.cs existant.
  2. Créez un fichier AssemblyInfo.tt à sa place. Visual Studio doit créer AssemblyInfo.cs et le regrouper avec le fichier T4 après avoir enregistré 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\\(\"(?\\d+)\\.(?\\d+)\\.(?\\d+)\\.(?\\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.ComstackrServices; 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: NeutralResourcesLanguageAtsortingbute( "en-US" )] <#+ int major = 1; int minor = 0; int revision = 0; int build = 0; #> 
  3. Ajoutez ceci à votre événement de pré-construction:

     "%CommonProgramFiles(x86)%\microsoft shared\TextTemplating\$(VisualStudioVersion)\TextTransform.exe" -a !!BuildConfiguration!$(Configuration) "$(ProjectDir)Properties\AssemblyInfo.tt" 

Si vous placez un astérisque pour build et révision, Visual Studio utilise le nombre de jours depuis le 1er janvier 2000 comme numéro de build et le nombre de secondes depuis minuit divisé par 2 en tant que révision.

Une meilleure solution de sauvegarde de la vie est http://autobuildversion.codeplex.com/

Cela fonctionne comme un charme et c’est très flexible.

Voici la citation sur AssemblyInfo.cs de MSDN :

Vous pouvez spécifier toutes les valeurs ou vous pouvez accepter le numéro de build par défaut, le numéro de révision ou les deux en utilisant un astérisque ( ). Par exemple, [assembly: AssemblyVersion (“2.3.25.1”)] indique 2 comme version majeure, 3 comme version mineure, 25 comme numéro de version et 1 comme numéro de révision. Un numéro de version tel que [assembly: AssemblyVersion (“1.2. “)] Spécifie 1 comme version majeure, 2 comme version mineure et accepte les numéros de build et de révision par défaut. Un numéro de version tel que [assembly: AssemblyVersion (“1.2.15. *”)] Spécifie 1 comme version majeure, 2 comme version mineure, 15 comme numéro de version et accepte le numéro de révision par défaut. Le numéro de build par défaut s’incrémente chaque jour. Le numéro de révision par défaut est aléatoire

Cela dit effectivement, si vous mettez un 1.1. * Dans les informations d’assemblage, seul le numéro de construction sera auto-incrémenté, et cela ne se produira pas après chaque construction, mais quotidiennement. Le numéro de révision modifiera chaque version, mais aléatoirement, plutôt que de manière incrémentielle.

Ceci est probablement suffisant pour la plupart des cas d’utilisation. Si ce n’est pas ce que vous cherchez, vous êtes obligé d’écrire un script qui incrémentera la version # lors de l’étape de pré-construction

Utilisez AssemblyInfo.cs

Créez le fichier dans App_Code: et remplissez ce qui suit ou utilisez Google pour d’autres possibilités d’atsortingbut / 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.

Ensuite, si vous travaillez sur un site Web, dans une page aspx ou dans un contrôle, vous pouvez append la balise :

 ComstackrOptions="\App_Code\AssemblyInfo.cs" 

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

Je ne pense pas que vous ayez besoin d’append des options de compilation de quelque manière que ce soit pour d’autres classes; tous ceux de App_Code doivent recevoir les informations de version lors de leur compilation.

J’espère que cela pourra aider.

  • Star dans la version (comme “2.10.3. *”) – c’est simple, mais les nombres sont trop grands

  • AutoBuildVersion – a l’air génial mais ça ne marche pas sur mon VS2010.

  • Le script de @ DrewChapin fonctionne, mais dans mon studio, je ne peux pas définir différents modes pour l’événement de pré-génération Debug et l’événement de pré-compilation.

donc j’ai un peu changé le script …

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

et script (cela fonctionne pour les configurations “Debug” et “Release”):

 <#@ 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+\\.(?\\d+)\\.(?\\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.ComstackrServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of atsortingbutes. Change these atsortingbute 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 atsortingbute 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; #> 

Vous pouvez essayer d’utiliser UpdateVersion par Matt Griffith . C’est assez vieux maintenant, mais ça marche bien. Pour l’utiliser, il vous suffit de configurer un événement de pré-génération qui pointe vers votre fichier AssemblyInfo.cs, et l’application mettra à jour les numéros de version en conséquence, conformément aux arguments de la ligne de commande.

Comme l’application est open-source, j’ai également créé une version pour incrémenter le numéro de version en utilisant le format (version majeure). (Version mineure). ([Année] [jour de l’année]). (Incrément) . Plus d’informations à ce sujet et le code révisé sont disponibles sur mon entrée de blog, numéros de version d’assembly et .NET .

Mise à jour: J’ai mis le code de ma version modifiée de l’application UpdateVersion sur GitHub: https://github.com/munr/UpdateVersion

Vous pouvez effectuer des versions plus avancées en utilisant des scripts de génération tels que Build Versioning