visual tutorial studio para net framework dotnet configurar code asp c# visual-studio .net-core visual-studio-2017 .net-standard

c# - tutorial - dotnet



Versiones automáticas en Visual Studio 2017(.NET Core) (13)

Acepté la respuesta anterior porque @Gigi es correcta (a partir de ahora), pero estaba molesto y se me ocurrieron los siguientes scripts de PowerShell.

Primero tengo el script en mi carpeta de solución (UpdateBuildVersion.ps1):

#Get Path to csproj $path = "$PSScriptRoot/src/ProjectFolder/ProjectName.csproj" #Read csproj (XML) $xml = [xml](Get-Content $path) #Retrieve Version Nodes $assemblyVersion = $xml.Project.PropertyGroup.AssemblyVersion $fileVersion = $xml.Project.PropertyGroup.FileVersion #Split the Version Numbers $avMajor, $avMinor, $avBuild = $assemblyVersion.Split(".") $fvMajor, $fvMinor, $fvBuild = $fileVersion.Split(".") #Increment Revision $avBuild = [Convert]::ToInt32($avBuild,10)+1 $fvBuild = [Convert]::ToInt32($fvBuild,10)+1 #Put new version back into csproj (XML) $xml.Project.PropertyGroup.AssemblyVersion = "$avMajor.$avMinor.$avBuild" $xml.Project.PropertyGroup.FileVersion = "$fvMajor.$fvMinor.$fvBuild" #Save csproj (XML) $xml.Save($path)

Agregué esto al archivo csproj:

<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <AssemblyVersion>0.0.1</AssemblyVersion> <FileVersion>0.0.1</FileVersion> <PreBuildEvent>powershell.exe –NonInteractive –ExecutionPolicy Unrestricted -command "& {$(SolutionDir)UpdateBuildVersion.ps1}"</PreBuildEvent> </PropertyGroup> </Project>

Incluso a través de su configuración como PreBuildEvent, el hecho es que los números de versión no se actualizan hasta DESPUÉS de que el archivo se haya cargado en la memoria, por lo que el número de versión no se reflejará hasta la próxima compilación. De hecho, podría cambiarlo a un PostBuildEvent y tendría el mismo efecto.

También creé los siguientes dos scripts: (UpdateMinorVersion.ps1)

#Get Path to csproj $path = "$PSScriptRoot/src/ProjectFolder/ProjectName.csproj" #Read csproj (XML) $xml = [xml](Get-Content $path) #Retrieve Version Nodes $assemblyVersion = $xml.Project.PropertyGroup.AssemblyVersion $fileVersion = $xml.Project.PropertyGroup.FileVersion #Split the Version Numbers $avMajor, $avMinor, $avBuild = $assemblyVersion.Split(".") $fvMajor, $fvMinor, $fvBuild = $fileVersion.Split(".") #Increment Minor Version - Will reset all sub nodes $avMinor = [Convert]::ToInt32($avMinor,10)+1 $fvMinor = [Convert]::ToInt32($fvMinor,10)+1 $avBuild = 0 $fvBuild = 0 #Put new version back into csproj (XML) $xml.Project.PropertyGroup.AssemblyVersion = "$avMajor.$avMinor.$avBuild" $xml.Project.PropertyGroup.FileVersion = "$fvMajor.$fvMinor.$fvBuild" #Save csproj (XML) $xml.Save($path)

(UpdateMajorVersion.ps1)

#Get Path to csproj $path = "$PSScriptRoot/src/ProjectFolder/ProjectName.csproj" #Read csproj (XML) $xml = [xml](Get-Content $path) #Retrieve Version Nodes $assemblyVersion = $xml.Project.PropertyGroup.AssemblyVersion $fileVersion = $xml.Project.PropertyGroup.FileVersion #Split the Version Numbers $avMajor, $avMinor, $avBuild = $assemblyVersion.Split(".") $fvMajor, $fvMinor, $fvBuild = $fileVersion.Split(".") #Increment Major Version - Will reset all sub nodes $avMajor = [Convert]::ToInt32($avMajor,10)+1 $fvMajor = [Convert]::ToInt32($fvMajor,10)+1 $avMinor = 0 $fvMinor = 0 $avBuild = 0 $fvBuild = 0 #Put new version back into csproj (XML) $xml.Project.PropertyGroup.AssemblyVersion = "$avMajor.$avMinor.$avBuild" $xml.Project.PropertyGroup.FileVersion = "$fvMajor.$fvMinor.$fvBuild" #Save csproj (XML) $xml.Save($path)

Pasé la mayor parte de unas horas tratando de encontrar una manera de incrementar automáticamente las versiones en .NETCoreApp 1.1 (Visual Studio 2017).

Sé que el AssemblyInfo.cs se está creando dinámicamente en la carpeta: obj/Debug/netcoreapp1.1/

No acepta el método anterior de: [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.*")]

Si configuro el proyecto para empaquetar, puedo configurar versiones allí, pero esto parece ser utilizado para construir el archivo AssemblyInfo.cs.

Mi pregunta es, ¿alguien ha descubierto cómo controlar la versión en proyectos .NET Core (o .NETStandard para el caso).


Creo que esta Answer de @joelsand es la respuesta correcta para configurar el número de versión para el núcleo dotnet que se ejecuta en VSTS

Para agregar más información para esta respuesta,

BUILD_BUILDNUMBER es en realidad una variable predefinida .

Resulta que hay 2 versiones de variable predefinida.

Uno es build.xxxx, el otro es BUILD_XXXX.

Solo puede usar el Environment Variable Name en cproj.


Estos valores ahora se establecen en el archivo .csproj :

<PropertyGroup> <TargetFramework>netcoreapp1.1</TargetFramework> <AssemblyVersion>1.0.6.0</AssemblyVersion> <FileVersion>1.0.6.0</FileVersion> <Version>1.0.1</Version> </PropertyGroup>

Estos son los mismos valores que ve si va a la pestaña Paquete en la configuración del proyecto. Si bien no creo que pueda usar * para aumentar automáticamente la versión, lo que puede hacer es introducir un paso de procesamiento posterior que reemplace las versiones por usted (por ejemplo, como parte de su integración continua).


He estado buscando un incrementador de versión para una aplicación Net Core en VS2017 usando el formato de configuración csproj.

Encontré un proyecto llamado dotnet bump que funcionó para el formato project.json pero luchó por encontrar una solución para el formato .csproj. El escritor the the dotnet bump realmente encontró la solución para el formato .csproj y se llama MSBump.

Hay un proyecto en GitHub para ello en:

https://github.com/BalassaMarton/MSBump

donde puede ver el código y también está disponible en Nuget. Simplemente busque MSBump en Nuget.


Hice una herramienta CLI simple para configurar cadenas de versión .csproj .NET Core here . Puede combinarlo con herramientas como GitVersion para el salto automático de versión durante las compilaciones de CI, si eso es lo que busca.



Podemos utilizar parámetros especiales para dotnet publish -- version-suffix 1.2.3

Para la versión del archivo:

<AssemblyVersion Condition=" ''$(VersionSuffix)'' == '''' ">0.0.1.0</AssemblyVersion> <AssemblyVersion Condition=" ''$(VersionSuffix)'' != '''' ">$(VersionSuffix)</AssemblyVersion>

Para la versión:

<Version Condition=" ''$(VersionSuffix)'' == '''' ">0.0.1</Version> <Version Condition=" ''$(VersionSuffix)'' != '''' ">$(VersionSuffix)</Version>

https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publish?tabs=netcore21

--version-suffix <VERSION_SUFFIX> Defines the value for the $(VersionSuffix) property in the project.


Puede usar una función de propiedad MSBuild para establecer el sufijo de la versión según la fecha actual:

<PropertyGroup Condition=" ''$(Configuration)'' == ''Debug'' "> <VersionSuffix>pre$([System.DateTime]::UtcNow.ToString(yyyyMMdd-HHmm))</VersionSuffix> </PropertyGroup>

Esto generará un paquete con un nombre como: PackageName.1.0.0-pre20180807-1711.nupkg .

Más detalles sobre las funciones de propiedad de MSBuild: https://docs.microsoft.com/en-us/visualstudio/msbuild/property-functions


Se me ocurrió una solución que funcionaba casi igual que el antiguo atributo AssemblyVersion con star (*) - AssemblyVersion ("1.0. ") *

Los valores de AssemblyVersion y AssemblyFileVersion están en el archivo .csproj del proyecto MSBuild (no en AssemblyInfo.cs ) como propiedad FileVersion (genera AssemblyFileVersionAttribute ) y AssemblyVersion (genera AssemblyVersionAttribute ). En el proceso MSBuild, usamos nuestra tarea personalizada MSBuild para generar números de versión y luego anulamos los valores de estas propiedades FileVersion y AssemblyVersion con nuevos valores de la tarea.

Entonces, primero creamos nuestra tarea personalizada 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();     } }

La clase de tarea hereda de Microsoft.Build.Utilities.Task clase de Microsoft.Build.Utilities.Core NuGet package. Toma la propiedad BaseVersion (opcional) en la entrada y devuelve la versión generada en la propiedad de salida Versión. La lógica para obtener números de versión es la misma que la versión automática de .NET (el número de compilación es el recuento de días desde el 1/1/2000 y la revisión es medio segundo desde la medianoche).

Para construir esta tarea de MSBuild, utilizamos el tipo de proyecto de biblioteca de clases .NET Standard 1.3 con esta clase.

El archivo .csproj puede verse así:

<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>

Este proyecto de tarea también está disponible en mi GitHub holajan/DC.Build.Tasks

Ahora configuramos MSBuild para usar esta tarea y establecer las propiedades FileVersion y AssemblyVersion . En el archivo .csproj se ve así:

<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>

Cosas importantes aquí:

  • Mencionado UsingTask importa la tarea GetCurrentBuildVersion de DC.Build.Tasks.dll . Se supone que este archivo dll se encuentra en el directorio principal de su archivo .csproj.
  • Nuestro objetivo BeforeBuildActionsProject1 que llama a la tarea debe tener un nombre único por proyecto en caso de que tengamos más proyectos en la solución que llame a la tarea GetCurrentBuildVersion.

La ventaja de esta solución es que no solo funciona desde compilaciones en el servidor de compilación, sino también en compilaciones manuales desde la compilación de dotnet o Visual Studio.


Si está utilizando Visual Studio Team Services / TFS o algún otro proceso de compilación de CI para tener versiones integradas, puede utilizar el atributo Condition de msbuild, por ejemplo:

msbuild /t:build /p:Version=YourVersionNumber /p:AssemblyVersion=YourVersionNumber

Esto le indicará al compilador .NET Core que use lo que esté en la variable de entorno BUILD_BUILDNUMBER si está presente, o recurra a 0.0.1-local si está haciendo una compilación en su máquina local.


dotnet build /p:AssemblyVersion=1.2.3.4

Estaba respondiendo a: "¿Alguien ha descubierto cómo controlar la versión en proyectos .NET Core (o .NETStandard para el caso)". Encontré esta pregunta tratando de resolver este problema en el contexto de una compilación de CI. Quería establecer la versión de ensamblaje en el número de compilación de CI.


Agregue <Deterministic>False</Deterministic> dentro de una sección <PropertyGroup> de .csproj

La solución para hacer que AssemblyVersion * funcione se describe en "Mensaje de error confuso para comodín en [AssemblyVersion] en .Net Core # 22660"

Los comodines solo se permiten si la compilación no es determinista, que es el valor predeterminado para los proyectos .Net Core. Agregar <Deterministic>False</Deterministic> a csproj soluciona el problema.

Los motivos por los que los Desarrolladores de .Net Core consideran beneficiosas las Construcciones deterministas se describen en http://blog.paranoidcoding.com/2016/04/05/deterministic-builds-in-roslyn.html y los compiladores deben ser deterministas: las mismas entradas generan las mismas salidas # 372

Sin embargo, si está utilizando TeamCity, TFS u otra herramienta de CI / CD, probablemente sea mejor mantener el número de versión controlado e incrementado por ellos y pasar a construir como parámetro (como se sugirió en otras respuestas), por ejemplo

msbuild /t:pack /p:Version=YourVersionNumber

Número de paquete para paquetes NuGet

<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <Version Condition=" ''$(BUILD_BUILDNUMBER)'' == '''' ">0.0.1-local</Version> <Version Condition=" ''$(BUILD_BUILDNUMBER)'' != '''' ">$(BUILD_BUILDNUMBER)</Version> <TargetFramework>netcoreapp1.1</TargetFramework> </PropertyGroup> <ItemGroup> <Folder Include="wwwroot/" /> </ItemGroup> <ItemGroup> <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore" Version="1.1.2" /> <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="1.1.2" /> </ItemGroup> </Project>


Para habilitar el control de versiones de su .Net Core / .Net Sea cual sea el proyecto basado en su configuración de GIT, utilice las etiquetas / describa la funcionalidad de GIT.

He estado usando un archivo Prebuild.targets.xml que se encuentra en la carpeta raíz del proyecto y se incluye en el archivo csproj como:

<Project Sdk="Microsoft.NET.Sdk"> <Import Project="PreBuild.targets.xml" /> ... <PropertyGroup> <GenerateAssemblyInfo>false</GenerateAssemblyInfo>

Use la etiqueta "GenerateAssembyInfo" para deshabilitar la generación automática de información de ensamblaje.

Luego, Prebuild.targets.xml generará un archivo CommonAssemblyInfo.cs donde puede incluir las etiquetas de versión que desee en función de su versión GIT

NOTA: He encontrado Prebuilds.targets.xml en otro lugar, así que no me he molestado en limpiarlo).

El archivo Prebuild.targets.xml:

<?xml version="1.0" encoding="utf-8" ?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <UsingTask TaskName="GetVersion" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)/Microsoft.Build.Tasks.v4.0.dll" > <ParameterGroup> <VersionString ParameterType="System.String" Required="true" /> <Version ParameterType="System.String" Output="true" /> <Commit ParameterType="System.String" Output="true" /> <VersionSuffix ParameterType="System.String" Output="true" /> </ParameterGroup> <Task> <!--<Reference Include="" />--> <Using Namespace="System"/> <Using Namespace="System.IO"/> <Using Namespace="System.Text.RegularExpressions" /> <Code Type="Fragment" Language="cs"> <![CDATA[ var match = Regex.Match(VersionString, @"^(?<major>/d+)/.(?<minor>/d+)(/.?(?<patch>/d+))?-(?<revision>/d+)-(?<commit>[a-z0-9-]+)$"); int major, minor, patch, revision; Int32.TryParse(match.Groups["major"].Value, out major); Int32.TryParse(match.Groups["minor"].Value, out minor); Int32.TryParse(match.Groups["patch"].Value, out patch); Int32.TryParse(match.Groups["revision"].Value, out revision); _Version = new Version(major, minor, patch, revision).ToString(); _Commit = match.Groups["commit"].Value; ]]> </Code> </Task> </UsingTask> <UsingTask TaskName="GitExistsInPath" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)/Microsoft.Build.Tasks.v4.0.dll" > <ParameterGroup> <Exists ParameterType="System.Boolean" Output="true" /> </ParameterGroup> <Task> <!--<Reference Include="" />--> <Using Namespace="System"/> <Using Namespace="System.IO"/> <Using Namespace="System.Text.RegularExpressions" /> <Code Type="Fragment" Language="cs"> <![CDATA[ var values = Environment.GetEnvironmentVariable("PATH"); foreach (var path in values.Split('';'')) { var exeFullPath = Path.Combine(path, "git.exe"); if (File.Exists(exeFullPath)) { Exists = true; return true; } var cmdFullPath = Path.Combine(path, "git.cmd"); if (File.Exists(cmdFullPath)) { Exists = true; return true; } } Exists = false; ]]> </Code> </Task> </UsingTask> <Target Name="CreateCommonVersionInfo" BeforeTargets="CoreCompile"> <Message Importance="high" Text="CreateCommonVersionInfo" /> <GitExistsInPath> <Output TaskParameter="Exists" PropertyName="GitExists"/> </GitExistsInPath> <Message Importance="High" Text="git not found!" Condition="!$(GitExists)"/> <Exec Command="git describe --tags --long --dirty > $(ProjectDir)version.txt" Outputs="$(ProjectDir)version.txt" WorkingDirectory="$(SolutionDir)" IgnoreExitCode="true" Condition="$(GitExists)"> <Output TaskParameter="ExitCode" PropertyName="ExitCode" /> </Exec> <Message Importance="high" Text="Calling git failed with exit code $(ExitCode)" Condition="$(GitExists) And ''$(ExitCode)''!=''0''" /> <ReadLinesFromFile File="$(ProjectDir)version.txt" Condition="$(GitExists) And ''$(ExitCode)''==''0''"> <Output TaskParameter="Lines" ItemName="OutputLines"/> </ReadLinesFromFile> <Message Importance="High" Text="Tags: @(OutputLines)" Condition="$(GitExists) And ''$(ExitCode)''==''0''"/> <Delete Condition="Exists(''$(ProjectDir)version.txt'')" Files="$(ProjectDir)version.txt"/> <GetVersion VersionString="@(OutputLines)" Condition="$(GitExists) And ''$(ExitCode)''==''0''"> <Output TaskParameter="Version" PropertyName="VersionString"/> <Output TaskParameter="Commit" PropertyName="Commit"/> </GetVersion> <PropertyGroup> <VersionString Condition="''$(VersionString)''==''''">0.0.0.0</VersionString> </PropertyGroup> <Message Importance="High" Text="Creating CommonVersionInfo.cs with version $(VersionString) $(Commit)" /> <WriteLinesToFile Overwrite="true" File="$(ProjectDir)CommonAssemblyInfo.cs" Encoding="UTF-8" Lines=''using System.Reflection%3B // full version: $(VersionString)-$(Commit) [assembly: AssemblyVersion("$(VersionString)")] [assembly: AssemblyInformationalVersion("$(VersionString)")] [assembly: AssemblyFileVersion("$(VersionString)")]'' /> </Target> </Project>

EDITAR: Si está construyendo usando MSBUILD, el

$(SolutionDir)

Podría causarte problemas, usa

$(ProjectDir)

en lugar