Я придумал решение, которое работало почти так же, как старый атрибут AssemblyVersion со звездочкой (*) - AssemblyVersion ("1.0. ") *
Значения для AssemblyVersion и AssemblyFileVersion находятся в файле .csproj проекта MSBuild (не в AssemblyInfo.cs ) как свойство FileVersion (генерирует AssemblyFileVersionAttribute ) и AssemblyVersion (генерирует AssemblyVersionAttribute ). В процессе MSBuild мы используем нашу настраиваемую задачу MSBuild для генерации номеров версий, а затем переопределяем значения этих свойств FileVersion и AssemblyVersion новыми значениями из задачи.
Итак, сначала мы создаем нашу настраиваемую задачу MSBuild GetCurrentBuildVersion :
public class GetCurrentBuildVersion : Task
{
[Output]
public string Version { get; set; }
public string BaseVersion { get; set; }
public override bool Execute()
{
var originalVersion = System.Version.Parse(this.BaseVersion ?? "1.0.0");
this.Version = GetCurrentBuildVersionString(originalVersion);
return true;
}
private static string GetCurrentBuildVersionString(Version baseVersion)
{
DateTime d = DateTime.Now;
return new Version(baseVersion.Major, baseVersion.Minor,
(DateTime.Today - new DateTime(2000, 1, 1)).Days,
((int)new TimeSpan(d.Hour, d.Minute, d.Second).TotalSeconds) / 2).ToString();
}
}
Задача класса унаследованы от Microsoft.Build.Utilities.Task класса из Microsoft.Build.Utilities.Core пакета NuGet. Он принимает свойство BaseVersion (необязательно) на входе и возвращает сгенерированную версию в свойстве вывода Version. Логика получения номеров версий такая же, как и для автоматического управления версиями .NET (номер сборки - это количество дней с 01.01.2000, а версия - полсекунды с полуночи).
Для создания этой задачи MSBuild мы используем тип проекта библиотеки классов .NET Standard 1.3 с этим классом.
Файл .csproj может выглядеть так:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.3</TargetFramework>
<AssemblyName>DC.Build.Tasks</AssemblyName>
<RootNamespace>DC.Build.Tasks</RootNamespace>
<PackageId>DC.Build.Tasks</PackageId>
<AssemblyTitle>DC.Build.Tasks</AssemblyTitle>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build.Framework" Version="15.1.1012" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.1.1012" />
</ItemGroup>
</Project>
Этот проект задачи также доступен в моем GitHub holajan / DC.Build.Tasks
Теперь мы настраиваем MSBuild для использования этой задачи и устанавливаем свойства FileVersion и AssemblyVersion . В файле .csproj это выглядит так:
<Project Sdk="Microsoft.NET.Sdk">
<UsingTask TaskName="GetCurrentBuildVersion" AssemblyFile="$(MSBuildThisFileFullPath)\..\..\DC.Build.Tasks.dll" />
<PropertyGroup>
...
<AssemblyVersion>1.0.0.0</AssemblyVersion>
<FileVersion>1.0.0.0</FileVersion>
</PropertyGroup>
...
<Target Name="BeforeBuildActionsProject1" BeforeTargets="BeforeBuild">
<GetCurrentBuildVersion BaseVersion="$(FileVersion)">
<Output TaskParameter="Version" PropertyName="FileVersion" />
</GetCurrentBuildVersion>
<PropertyGroup>
<AssemblyVersion>$(FileVersion)</AssemblyVersion>
</PropertyGroup>
</Target>
</Project>
Важные вещи здесь:
- Упомянутый UsingTask импортирует задачу GetCurrentBuildVersion из DC.Build.Tasks.dll . Предполагается, что этот файл DLL находится в родительском каталоге вашего файла .csproj.
- Наша цель BeforeBuildActionsProject1, которая вызывает задачу, должна иметь уникальное имя для каждого проекта на тот случай, если у нас есть больше проектов в решении, которое вызывает задачу GetCurrentBuildVersion.
Преимущество этого решения заключается в том, что оно работает не только из сборок на сервере сборки, но и в ручных сборках из сборки dotnet или Visual Studio.
/p:
флагdotnet msbuild
в свой скрипт сборки и установить версию, компанию, авторские права ... все это хорошее.