Как получить автоматически увеличивающийся номер версии (Visual Studio)?

Я хочу сохранить набор целых чисел, которые автоматически увеличиваются во время сборки:

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

Когда я скомпилирую, он будет автоматически увеличивать Revision. Когда я создам проект установки, он будет увеличивать MinorVersion (я в порядке с этим вручную). MajorVersion будет только увеличиваться вручную.

Затем я мог отображать номер версии в меню Справка/О пользователе пользователю:

  Version: 0.1.92

Как это можно достичь?

В этом вопросе возникает вопрос не только о том, как иметь номер с автоматической инкрементной версией, но и как использовать его в коде, который является более полным ответом, чем другие.

+361
источник поделиться
9 ответов

Если вы добавите класс AssemblyInfo в свой проект и внесите изменения в атрибут AssemblyVersion, чтобы завершить звездочку, например:

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

Visual studio увеличит окончательный номер для вас в соответствии с этими правилами (спасибо, у меня было это совершенно неправильно!)

Чтобы ссылаться на эту версию в коде, чтобы вы могли отобразить ее пользователю, вы используете отражение. Например,

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})";

Две важные ошибки, которые вы должны знать

От @ashes999:

Также стоит отметить, что если указаны как AssemblyVersion, так и AssemblyFileVersion, вы не увидите этого на своем .exe.

От @BrainSlugs83:

Установка только 4-го числа * может быть плохим, поскольку версия не всегда увеличивается. Третий номер - это количество дней с 2000 года, а четвертое число - это количество секунд с полуночи (разделено на 2). [ЭТО НЕ СЛУЧАЙНО]. Поэтому, если вы построили решение в конце дня один день, а на следующий день на следующий день более поздняя версия будет иметь более раннюю версию. Я рекомендую всегда использовать X.Y.* вместо X.Y.Z.*, потому что ваш номер версии будет ВСЕГДА увеличивать этот путь.

+481
источник

Вы можете использовать механизм шаблонов T4 в Visual Studio для генерации требуемого исходного кода из простого текстового файла:

Я хотел настроить генерацию информации о версии для некоторых .NET. проекты. Его долгое время я исследовал варианты, поэтому я искал в надежде найти простой способ сделать это. То, что я обнаружил, не выглядело очень обнадеживающим: люди пишут Надстройки Visual Studio и пользовательские задачи MsBuild, чтобы получить один целое число (хорошо, может быть, два). Это чувствовало избыток для небольшого личный проект.

Вдохновение вызвано одним из обсуждений StackOverflow, где кто-то предположил, что шаблоны T4 могут выполнять эту работу. И, конечно же, они могут. Решение требует минимальных усилий и отсутствие Visual Studio или настроить процесс сборки. Вот что должно быть сделано:

  • Создайте файл с расширением ".tt" и разместите там шаблон T4, который будет генерировать атрибуты AssemblyVersion и 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;
#>

Вам нужно будет решить алгоритм генерации номера версии. Для мне было достаточно, чтобы автогенерировать номер ревизии, который установлен на количество дней с 1 января 2010 года. Как вы можете видеть, правило генерации версий написано на простом С#, поэтому вы можете легко отрегулируйте его в соответствии с вашими потребностями.

  1. Файл, указанный выше, должен быть помещен в один из проектов. Я создал новый проект только с одним файлом для управления версиями техника четкая. Когда я создаю этот проект (на самом деле мне даже не нужно для его создания: сохранения файла достаточно, чтобы вызвать Visual Studio action), генерируется следующий С#:
// 
// 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")]

Да, сегодня его 113 дней с 1 января 2010 года. Завтра номер редакции изменится.

  1. Следующий шаг - удалить атрибуты AssemblyVersion и AssemblyFileVersion из файлов AssemblyInfo.cs во всех проектах, которые должны совместно использовать ту же самую автоматическую версию информации о версии. Вместо этого выберите "Добавить существующий элемент" для каждого проекта, перейдите в папку с T4 файл шаблона, выберите соответствующий ".cs" файл и добавьте его как ссылку. Это будет сделано!

Что мне нравится в этом подходе, так это то, что он легкий (нестандартный Задачи MsBuild), а также информация о автоматически сгенерированной версии не добавляется к управления источником. И, конечно, используя С# для генерации версии алгоритм открывается для алгоритмов любой сложности.

+138
источник
другие ответы

Связанные вопросы


Похожие вопросы

Если вы помещаете звездочку для сборки и ревизии, визуальная студия использует количество дней с 1 января 2000 года в качестве номера сборки и количество секунд с полуночи, разделенное на 2 как ревизия.

БОЛЬШЕ лучшее решение для спасения жизни http://autobuildversion.codeplex.com/

Он работает как шарм, и он ОЧЕНЬ гибкий.

+28
источник

Это моя реализация предложения T4... В принципе, если вы выполните шаги, описанные ниже, ваш проект будет увеличивать номер сборки каждый раз, когда вы строите проект независимо от выбранной конфигурации (например, Debug | Release) и он будет увеличивать номер ревизии каждый раз, когда вы выполняете сборку Release.

Для более подробного объяснения это будет читать существующий файл AssemblyInfo.cs и использовать регулярное выражение для поиска информации AssemblyVersion, а затем увеличивать числа ревизий и сборки на основе ввода из TextTransform.exe. Обратите внимание, что номера сборки и/или ревизии будут только увеличиваться при обработке с TextTransform.exe. Если вы сохраните файл .tt или щелкните его правой кнопкой мыши и нажмите "Запустить пользовательский инструмент", он оставит файл AssemblyInfo.cs неповрежденным. Также обратите внимание, что если AssemblyInfo.cs не существует, то он создаст его со значением 0 для сборки и ревизии.

Замените файл AssemblyInfo.cs на этот AssemblyInfo.tt файл:

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

<#
    bool incRevision = false;
    bool incBuild = false;

    try { incRevision = Convert.ToBoolean(this.Host.ResolveParameterValue("","","revision")); } catch( Exception ) { }
    try { incBuild = Convert.ToBoolean(this.Host.ResolveParameterValue("","","build")); } catch( Exception ) { }
    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?1:0);
        build = Convert.ToInt32(matches[0].Groups["build"].Value) + (incBuild?1:0);
    }
    catch( Exception ) { }
#>

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("1.0.<#= this.revision #>.<#= this.build #>")]
[assembly: AssemblyFileVersion("1.0.<#= this.revision #>.<#= this.build #>")]
[assembly: NeutralResourcesLanguageAttribute( "en-US" )]

<#+
    int revision = 0;
    int build = 0;
#>

Добавьте это в свое предварительное событие отладки:

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

Добавьте это к событию Pre-build Release:

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

Если вы используете проект веб-приложения, добавьте его в событие предварительной сборки:

if $(Configuration) == Debug "%CommonProgramFiles(x86)%\microsoft shared\TextTemplating\10.0\TextTransform.exe" -a !!build!true "$(ProjectDir)Properties\AssemblyInfo.tt"
if $(Configuration) == Release "%CommonProgramFiles(x86)%\microsoft shared\TextTemplating\10.0\TextTransform.exe" -a !!revision!true -a !!build!true "$(ProjectDir)Properties\AssemblyInfo.tt"



Обратите внимание, что вам, возможно, придется отрегулировать некоторые вещи, такие как путь к вашему файлу AssemblyInfo.tt, и в зависимости от вашей версии Visual Studio вам также придется настроить путь к TextTransform.exe.

+26
источник

Здесь quote на AssemblyInfo.cs из MSDN:

Вы можете указать все значения или может принять номер сборки по умолчанию, номер ревизии или оба с помощью звездочка(). Например, [Сборка: AssemblyVersion ( "2.3.25.1" )] указывает на 2 в качестве основной версии, 3 как младшая версия, 25 в качестве сборки номер и 1 в качестве номера ревизии. Номер версии, такой как [Сборка: AssemblyVersion ( "1.2" )] определяет 1 как основную версию, 2 как младшей версии, и принимает номера по умолчанию и ревизии по умолчанию. номер версии, такой как [Сборка: AssemblyVersion ( "1.2.15 *" )] определяет 1 как основную версию, 2 как младшая версия, 15 в качестве сборки номер и принимает значение по умолчанию номер ревизии. Строка по умолчанию число увеличивается каждый день. По умолчанию номер версии является случайным

Это эффективно говорит, что если вы введете 1.1. * в сборку, только номер сборки будет автоинкремент, и это произойдет не после каждой сборки, а ежедневно. Номер версии изменяет каждую сборку, но беспорядочно, а не пошагово.

Этого, вероятно, достаточно для большинства случаев использования. Если это не то, что вы ищете, вы застряли в написании script, который будет автоинкремент версии # на этапе предварительной сборки

+21
источник

Используйте AssemblyInfo.cs

Создайте файл в App_Code: и заполните следующее или используйте Google для других возможностей атрибута/свойства.

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 - это часть, на которой вы действительно находитесь.

Затем, если вы работаете на веб-сайте, на любой странице aspx или в элементе управления, вы можете добавить в <Page> тег:

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

(естественно, заменив путь к папке соответствующей переменной).

Я не считаю, что вам нужно добавлять параметры компилятора любым способом для других классов; все те, что в App_Code должны получать информацию о версии при компиляции.

Надеюсь, что это поможет.

+14
источник
  • Звезда в версии (например, "2.10.3. *" ) - это просто, но числа слишком большие

  • AutoBuildVersion - отлично смотрится, но его не работает на моем VS2010.

  • druciferre script работает, но я не могу в своей студии установить разные режимы для события предварительной сборки Debug и события Pre-build Release.

поэтому я немного изменил script... commamd:

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

и script (это работает с конфигурациями "Debug" и "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+\\.(?<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
источник

Вы можете попробовать использовать UpdateVersion от Matt Griffith. Сейчас он довольно старый, но работает хорошо. Чтобы использовать его, вам просто нужно настроить событие предварительной сборки, которое указывает на ваш файл AssemblyInfo.cs, и приложение будет соответствующим образом обновлять номера версий в соответствии с аргументами командной строки.

Поскольку приложение является открытым исходным кодом, я также создал версию, чтобы увеличить номер версии, используя формат (основная версия). (Малая версия). ([year] [dayofyear]). (increment). Более подробную информацию об этом и обновленном коде можно найти в моей записи в блоге Номера версий сборки и .NET.

Обновление: я поместил код для моей модифицированной версии приложения UpdateVersion в GitHub: https://github.com/munr/UpdateVersion strong >

+8
источник

Вы можете выполнить более расширенное управление версиями, используя скрипты сборки, такие как Build Versioning

+1
источник

Посмотрите другие вопросы по меткам или Задайте вопрос