Автоматически обновить номер версии

108

Я бы хотел, чтобы свойство версии моего приложения увеличивалось для каждой сборки, но я не уверен, как включить эту функцию в Visual Studio (2005/2008). Я пытался указать AssemblyVersion как 1.0. *, Но это не дает мне именно того, что я хочу.

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

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

Также приветствуется краткое объяснение того, как работает управление версиями. Когда увеличивается номер сборки и версии?

Роберт Хёглунд
источник
В следующем вопросе есть простое и удобное решение о том, как добавить номер сборки в ваше приложение, создав исходный файл в событии сборки. stackoverflow.com/questions/4450231/…
Эшли Дэвис

Ответы:

96

С «встроенным» материалом вы не можете, так как использование 1.0. * Или 1.0.0. * Заменит номера ревизии и сборки на закодированную дату / время, что обычно также является хорошим способом.

Дополнительные сведения см. В документации компоновщика сборок в теге / v.

Что касается автоматического увеличения чисел, используйте задачу AssemblyInfo:

AssemblyInfo Задача

Это можно настроить для автоматического увеличения номера сборки.

Есть 2 ошибки:

  1. Каждое из 4 чисел в строке версии ограничено 65535. Это ограничение Windows и вряд ли будет исправлено.
  2. Использование with с Subversion требует небольших изменений:

Тогда получить номер версии довольно просто:

Version v = Assembly.GetExecutingAssembly().GetName().Version;
string About = string.Format(CultureInfo.InvariantCulture, @"YourApp Version {0}.{1}.{2} (r{3})", v.Major, v.Minor, v.Build, v.Revision);

И, чтобы уточнить: в .net или, по крайней мере, в C #, сборка на самом деле является ТРЕТЬИМ номером, а не четвертым, как могли ожидать некоторые люди (например, разработчики Delphi, которые привыкли к Major.Minor.Release.Build).

В .net это Major.Minor.Build.Revision.

Майкл Штум
источник
3
я только что нашел этот Visual Studio надстройка, которая делает что - то подобное: autobuildversion.codeplex.com
jrsconfitto
6
Означает ли это, что 4 июня 2179 года номера версий Microsoft по умолчанию выйдут из строя? (65536-й день после 2000 г.)
Ллойд Пауэлл
1
@Jugglingnutcase - эта ссылка была бы почти идеальной, если бы она работала для текущих версий визуальной студии
Kraang Prime
2
@SanuelJackson ха-ха! да, было бы. Жаль, что я не успеваю за своими комментариями за 2010 год, извините! : P Марш времени и версий печалит всех нас.
jrsconfitto 05
@Michael Stum: Не могли бы вы обновить ссылку на AssemblyInfo Task в своем ответе? Для меня он загружается некорректно.
Мэтт
22

VS.NET по умолчанию устанавливает версию сборки 1.0. * И использует следующую логику при автоматическом увеличении: он устанавливает часть сборки на количество дней с 1 января 2000 года и устанавливает часть ревизии на количество секунд с полуночи, местное время, разделенное на два. См. Эту статью MSDN .

Версия сборки находится в файле assemblyinfo.vb или assemblyinfo.cs. Из файла:

' Version information for an assembly consists of the following four values:
'
'      Major Version
'      Minor Version 
'      Build Number
'      Revision
'
' You can specify all the values or you can default the Build and Revision Numbers 
' by using the '*' as shown below:
' <Assembly: AssemblyVersion("1.0.*")> 

<Assembly: AssemblyVersion("1.0.0.0")> 
<Assembly: AssemblyFileVersion("1.0.0.0")> 
Solracnapod
источник
Спасибо за January 1st, 2000
указание
11

Я обнаружил, что достаточно просто отображать дату последней сборки, используя следующее везде, где требуется версия продукта:

System.IO.File.GetLastWriteTime(System.Reflection.Assembly.GetExecutingAssembly().Location).ToString("yyyy.MM.dd.HH.mm.ss")

Вместо того, чтобы пытаться получить версию из следующего:

System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
object[] attributes = assembly.GetCustomAttributes(typeof(System.Reflection.AssemblyFileVersionAttribute), false);
object attribute = null;

if (attributes.Length > 0)
{
    attribute = attributes[0] as System.Reflection.AssemblyFileVersionAttribute;
}
user8128167
источник
6
Я думаю, вы имели в виду это: гггг.ММ.дд.ЧХмм, а не гггг.ММ.дд.ЧЧММ.
JHubbard80 02
1
Это простейшее решение, позволяющее привязать какой-либо номер версии к изменению файла сборки.
Алексей
6

Какую систему управления версиями вы используете?

Почти все они имеют ту или иную форму тега $ Id $, который раскрывается при возврате файла.

Я обычно использую какую-либо форму хакерства, чтобы отобразить это как номер версии.

Другой вариант - использовать дату в качестве номера сборки: 080803-1448.

engtech
источник
Можете ли вы развить тему «Почти все они имеют какую-либо форму тега $ Id $, который расширяется при возврате файла». Конкретно вы знаете о подрывной деятельности?
Greg B,
3

[Visual Studio 2017, свойства .csproj ]

Чтобы автоматически обновить свойство PackageVersion / Version / AssemblyVersion (или любое другое свойство), сначала создайте новый Microsoft.Build.Utilities.Taskкласс, который получит ваш текущий номер сборки и отправит обратно обновленный номер (я рекомендую создать отдельный проект только для этого класса).

Я вручную обновляю номера major.minor, но позволяю MSBuild автоматически обновлять номер сборки (1.1. 1 , 1.1. 2 , 1.1. 3 и т. Д. :)

using Microsoft.Build.Framework;
using System;
using System.Collections.Generic;
using System.Text;

public class RefreshVersion : Microsoft.Build.Utilities.Task
{
    [Output]
    public string NewVersionString { get; set; }
    public string CurrentVersionString { get; set; } 

    public override bool Execute()
    {       
        Version currentVersion = new Version(CurrentVersionString ?? "1.0.0");

        DateTime d = DateTime.Now;
        NewVersionString = new Version(currentVersion.Major, 
            currentVersion.Minor, currentVersion.Build+1).ToString();
        return true;
    }

}

Затем вызовите недавно созданную задачу в процессе MSBuild, добавив следующий код в файл .csproj:

<Project Sdk="Microsoft.NET.Sdk">    
...
<UsingTask TaskName="RefreshVersion" AssemblyFile="$(MSBuildThisFileFullPath)\..\..\<dll path>\BuildTasks.dll" />
<Target Name="RefreshVersionBuildTask" BeforeTargets="Pack" Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
   <RefreshVersion CurrentVersionString="$(PackageVersion)">
          <Output TaskParameter="NewVersionString" PropertyName="NewVersionString" />             
   </RefreshVersion>
   <Message Text="Updating package version number to $(NewVersionString)..." Importance="high" />
   <XmlPoke XmlInputPath="$(MSBuildProjectDirectory)\mustache.website.sdk.dotNET.csproj" Query="/Project/PropertyGroup/PackageVersion" Value="$(NewVersionString)" />
</Target>
...
<PropertyGroup>
 ..
 <PackageVersion>1.1.4</PackageVersion>
 ..

При выборе варианта проекта Visual Studio Pack (просто измените значение на BeforeTargets="Build"для выполнения задачи перед сборкой) код RefreshVersion будет запущен для вычисления нового номера версии, и XmlPokeзадача соответственно обновит ваше свойство .csproj (да, он изменит файл).

При работе с библиотеками NuGet я также отправляю пакет в репозиторий NuGet, просто добавляя следующую задачу сборки в предыдущий пример.

<Message Text="Uploading package to NuGet..." Importance="high" />
<Exec WorkingDirectory="$(MSBuildProjectDirectory)\bin\release" Command="c:\nuget\nuget push *.nupkg -Source https://www.nuget.org/api/v2/package" IgnoreExitCode="true" />

c:\nuget\nugetэто то место, где у меня есть клиент NuGet (не забудьте сохранить ключ API NuGet, позвонив nuget SetApiKey <my-api-key>или включив ключ в push-вызов NuGet).

На всякий случай кому-то поможет ^ _ ^.

Начо Колл
источник
1

Некоторое время назад я написал быстрый и грязный exe, который обновлял номер версии в файле assemblyinfo. {Cs / vb} - я также использовал rxfind.exe (простой и мощный инструмент замены поиска на основе регулярных выражений) для выполнения обновление из командной строки как часть процесса сборки. Еще пара полезных советов:

  1. разделите информацию о сборке на части продукта (название компании, версия и т. д.) и отдельные части сборки (название сборки и т. д.). Смотрите здесь
  2. Кроме того, я использую Subversion, поэтому я счел полезным установить номер сборки на номер версии Subversion, что позволяет очень легко всегда возвращаться к кодовой базе, которая сгенерировала сборку (например, 1.4.100.1502 был построен из ревизии 1502).
Кэйден
источник
Если это для файла кода ( .cs / .vb), вы должны вместо этого использовать шаблон T4.
BrainSlugs83
0

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

user283258
источник
Интересный. У меня уже много лет есть свой собственный с тем же именем, и я не знал, что он существует (хотя я только что выложил его в Интернете недавно): github.com/rjamesnw/VersionUpdater
Джеймс Уилкинс