Я хочу сохранить набор целых чисел, которые автоматически увеличиваются во время сборки:
int MajorVersion = 0;
int MinorVersion = 1;
int Revision = 92;
Когда я скомпилирую, он будет автоматически увеличивать Revision
. Когда я создам проект установки, он будет увеличивать MinorVersion
(я в порядке с этим вручную). MajorVersion
будет только увеличиваться вручную.
Затем я мог отображать номер версии в меню Справка/О пользователе пользователю:
Version: 0.1.92
Как это можно достичь?
В этом вопросе возникает вопрос не только о том, как иметь номер с автоматической инкрементной версией, но и как использовать его в коде, который является более полным ответом, чем другие.
Если вы добавите класс 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})";
Также стоит отметить, что если указаны как AssemblyVersion
, так и AssemblyFileVersion
, вы не увидите этого на своем .exe.
Установка только 4-го числа *
может быть плохим, поскольку версия не всегда увеличивается.
Третий номер - это количество дней с 2000 года, а четвертое число - это количество секунд с полуночи (разделено на 2). [ЭТО НЕ СЛУЧАЙНО]. Поэтому, если вы построили решение в конце дня один день, а на следующий день на следующий день более поздняя версия будет иметь более раннюю версию. Я рекомендую всегда использовать X.Y.*
вместо X.Y.Z.*
, потому что ваш номер версии будет ВСЕГДА увеличивать этот путь.
AssemblyVersion
и AssemblyFileVersion
, вы не увидите этого в вашем .exe
Вы можете использовать механизм шаблонов 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 года. Как вы можете видеть, правило генерации версий написано на простом С#, поэтому вы можете легко отрегулируйте его в соответствии с вашими потребностями.
- Файл, указанный выше, должен быть помещен в один из проектов. Я создал новый проект только с одним файлом для управления версиями техника четкая. Когда я создаю этот проект (на самом деле мне даже не нужно для его создания: сохранения файла достаточно, чтобы вызвать 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 года. Завтра номер редакции изменится.
- Следующий шаг - удалить атрибуты AssemblyVersion и AssemblyFileVersion из файлов AssemblyInfo.cs во всех проектах, которые должны совместно использовать ту же самую автоматическую версию информации о версии. Вместо этого выберите "Добавить существующий элемент" для каждого проекта, перейдите в папку с T4 файл шаблона, выберите соответствующий ".cs" файл и добавьте его как ссылку. Это будет сделано!
Что мне нравится в этом подходе, так это то, что он легкий (нестандартный Задачи MsBuild), а также информация о автоматически сгенерированной версии не добавляется к управления источником. И, конечно, используя С# для генерации версии алгоритм открывается для алгоритмов любой сложности.
Если вы помещаете звездочку для сборки и ревизии, визуальная студия использует количество дней с 1 января 2000 года в качестве номера сборки и количество секунд с полуночи, разделенное на 2 как ревизия.
БОЛЬШЕ лучшее решение для спасения жизни http://autobuildversion.codeplex.com/
Он работает как шарм, и он ОЧЕНЬ гибкий.
Это моя реализация предложения 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
.
AssemblyInfo.cs
вручную перед сборкой. Введите число на один меньше, чем вы хотите. Итак, если вы хотите 5
, то введите 4
.
Здесь 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, который будет автоинкремент версии # на этапе предварительной сборки
Используйте 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 должны получать информацию о версии при компиляции.
Надеюсь, что это поможет.
Звезда в версии (например, "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;
#>
Вы можете попробовать использовать UpdateVersion от Matt Griffith. Сейчас он довольно старый, но работает хорошо. Чтобы использовать его, вам просто нужно настроить событие предварительной сборки, которое указывает на ваш файл AssemblyInfo.cs, и приложение будет соответствующим образом обновлять номера версий в соответствии с аргументами командной строки.
Поскольку приложение является открытым исходным кодом, я также создал версию, чтобы увеличить номер версии, используя формат (основная версия). (Малая версия). ([year] [dayofyear]). (increment). Более подробную информацию об этом и обновленном коде можно найти в моей записи в блоге Номера версий сборки и .NET.
Обновление: я поместил код для моей модифицированной версии приложения UpdateVersion в GitHub: https://github.com/munr/UpdateVersion strong >
Вы можете выполнить более расширенное управление версиями, используя скрипты сборки, такие как Build Versioning