Atualizar automaticamente o número da versão

108

Gostaria que a propriedade de versão do meu aplicativo fosse incrementada para cada compilação, mas não tenho certeza de como habilitar essa funcionalidade no Visual Studio (2005/2008). Tentei especificar AssemblyVersion como 1.0. * Mas não me deu exatamente o que desejo.

Também estou usando um arquivo de configurações e, em tentativas anteriores, quando a versão do assembly mudou, minhas configurações foram redefinidas para o padrão, pois o aplicativo procurou o arquivo de configurações em outro diretório.

Gostaria de poder exibir um número de versão na forma de 1.1.38 para que, quando um usuário encontrar um problema, eu possa registrar a versão que ele está usando e também informá-lo para atualizar se tiver uma versão antiga.

Uma breve explicação de como funciona o controle de versão também seria apreciada. Quando o número de construção e revisão é incrementado?

Robert Höglund
fonte
A pergunta a seguir tem uma solução simples e conveniente de como injetar um número de compilação em seu aplicativo, gerando um arquivo de origem em um evento de compilação. stackoverflow.com/questions/4450231/…
Ashley Davis

Respostas:

96

Com o material "Integrado", você não pode, pois usar 1.0. * Ou 1.0.0. * Substituirá os números da revisão e da compilação por uma data / carimbo de data / hora codificados, o que normalmente também é uma boa maneira.

Para obter mais informações, consulte a documentação do Assembly Linker na tag / v.

Para incrementar automaticamente os números, use a Tarefa AssemblyInfo:

Tarefa AssemblyInfo

Isso pode ser configurado para incrementar automaticamente o número do build.

Existem 2 pegadinhas:

  1. Cada um dos 4 números na string de versão é limitado a 65535. Esta é uma limitação do Windows e improvável que seja corrigida.
  2. Usar com o Subversion requer uma pequena mudança:

Recuperar o número da versão é muito fácil:

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

E, para esclarecer: Em .net ou pelo menos em C #, a compilação é na verdade o TERCEIRO número, não o quarto como algumas pessoas (por exemplo, os desenvolvedores Delphi que estão acostumados com Major.Minor.Release.Build) podem esperar.

Em .net, é Major.Minor.Build.Revision.

Michael Stum
fonte
3
Eu encontrei este visual studio suplemento que faz algo semelhante: autobuildversion.codeplex.com
jrsconfitto
6
Isso significa que em 4 de junho de 2179 os números de versão padrão da Microsoft serão interrompidos? (65536º dia após 2000)
Lloyd Powell
1
@Jugglingnutcase - esse link seria quase perfeito, se funcionasse para as versões atuais do estúdio visual
Kraang Prime
2
@SanuelJackson haha! sim, seria. pena que não acompanho os meus comentários de 2010, desculpa! : P A marcha do tempo e das versões entristece a todos nós.
jrsconfitto
@Michael Stum: Você poderia atualizar o link da tarefa AssemblyInfo em sua resposta? Para mim, ele não está carregando corretamente.
Matt
22

O VS.NET padroniza a versão do Assembly para 1.0. * E usa a seguinte lógica ao auto-incrementar: ele define a parte de construção para o número de dias desde 1º de janeiro de 2000 e define a parte de revisão para o número de segundos desde a meia-noite, hora local, dividida por dois. Consulte este artigo do MSDN .

A versão do assembly está localizada em um arquivo assemblyinfo.vb ou assemblyinfo.cs. Do arquivo:

' 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
fonte
Obrigado por incluir a data inicial:January 1st, 2000
kiewic
11

Descobri que funciona bem simplesmente exibir a data da última compilação usando o seguinte sempre que uma versão do produto for necessária:

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

Em vez de tentar obter a versão de algo como o seguinte:

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
fonte
6
Acho que você quer dizer o seguinte: aaaa.MM.dd.HHmm não aaaa.MM.dd.HHMM.
JHubbard80
1
Esta é a solução mais simples para ter algum tipo de número de versão anexado à alteração do arquivo de montagem.
Alexei
6

Qual sistema de controle de origem você está usando?

Quase todos eles têm alguma forma de tag $ Id $ que é expandida quando o arquivo é verificado.

Eu geralmente uso alguma forma de hackery para exibir isso como o número da versão.

A outra alternativa é usar a data como o número da compilação: 080803-1448

Engtech
fonte
Você pode expandir em "Quase todos eles têm alguma forma de tag $ Id $ que é expandida quando o arquivo é verificado". Especificamente, você sabe por subversão?
Greg B
3

[Visual Studio 2017, propriedades .csproj ]

Para atualizar automaticamente sua propriedade PackageVersion / Version / AssemblyVersion (ou qualquer outra propriedade), primeiro, crie uma nova Microsoft.Build.Utilities.Taskclasse que obterá seu número de compilação atual e enviará de volta o número atualizado (recomendo criar um projeto separado apenas para essa classe).

Eu atualizo manualmente os números major.minor, mas deixo o MSBuild atualizar automaticamente o número da compilação (1.1. 1 , 1.1. 2 , 1.1. 3 , etc. :)

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

}

Em seguida, chame sua tarefa recém-criada no processo MSBuild, adicionando o próximo código em seu arquivo .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>
 ..

Ao escolher a opção de projeto do Visual Studio Pack (apenas altere para BeforeTargets="Build"para executar a tarefa antes de Build), o código RefreshVersion será acionado para calcular o novo número de versão e a XmlPoketarefa atualizará sua propriedade .csproj de acordo (sim, ela modificará o arquivo).

Ao trabalhar com bibliotecas NuGet, também envio o pacote para o repositório NuGet apenas adicionando a próxima tarefa de compilação ao exemplo anterior.

<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é onde eu tenho o cliente NuGet (lembre-se de salvar sua chave de API NuGet chamando nuget SetApiKey <my-api-key>ou para incluir a chave na chamada push do NuGet).

Apenas no caso de ajudar alguém ^ _ ^.

Nacho Coll
fonte
1

Algum tempo atrás eu escrevi um exe rápido e sujo que iria atualizar a versão # em um assemblyinfo. {Cs / vb} - Eu também usei rxfind.exe (uma ferramenta de substituição de pesquisa simples e poderosa baseada em regex) para fazer o atualização de uma linha de comando como parte do processo de construção. Algumas outras dicas úteis:

  1. separe as informações de montagem em peças do produto (nome da empresa, versão, etc.) e peças específicas da montagem (nome da montagem, etc.). Veja aqui
  2. Além disso - eu uso o subversion, então achei útil definir o número da compilação para o número da revisão do subversion, tornando muito fácil sempre voltar para a base de código que gerou a montagem (por exemplo, 1.4.100.1502 foi construída a partir da revisão 1502).
Caryden
fonte
Se for para um arquivo de código ( .cs / .vb), você deve usar um modelo T4.
BrainSlugs83,
0

Se quiser um número de incremento automático que seja atualizado sempre que uma compilação for concluída, você pode usar VersionUpdater a partir de um evento de pré-construção. Seu evento de pré-compilação pode verificar a configuração de compilação se você preferir, de modo que o número da versão só seja incrementado para uma compilação de lançamento (por exemplo).

user283258
fonte
Interessante. Há anos eu tenho o meu com o mesmo nome e não sabia que existia (embora eu o tenha colocado online recentemente): github.com/rjamesnw/VersionUpdater
James Wilkins