113

我希望每次构建都增加我的应用程序的版本属性,但我不确定如何在 Visual Studio (2005/2008) 中启用此功能。我试图将 AssemblyVersion 指定为 1.0.*,但它并没有得到我想要的。

我也在使用设置文件,并且在早期尝试中,当程序集版本更改时,我的设置被重置为默认值,因为应用程序在另一个目录中查找设置文件。

我希望能够以 1.1.38 的形式显示版本号,因此当用户发现问题时,我可以记录他们正在使用的版本,并告诉他们如果他们有旧版本进行升级。

对版本控制如何工作的简短解释也将不胜感激。内部版本号和修订号何时增加?

4

8 回答 8

97

使用“内置”的东西,你不能,因为使用 1.0.* 或 1.0.0.* 将用编码的日期/时间戳替换修订和内部版本号,这通常也是一个好方法。

有关详细信息,请参阅 /v 标记中的程序集链接器文档。

至于自动递增数字,请使用 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# 中,构建实际上是第三个数字,而不是某些人(例如习惯于 Major.Minor.Release.Build 的 Delphi 开发人员)可能期望的第四个。

在 .net 中,它是 Major.Minor.Build.Revision。

于 2008-08-03T11:41:38.490 回答
21

VS.NET 默认 Assembly 版本为 1.0.* 并在自动递增时使用以下逻辑:它将构建部分设置为自 2000 年 1 月 1 日以来的天数,并将修订部分设置为自午夜以来的秒数,当地时间,除以二。请参阅此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")> 
于 2008-09-30T20:58:08.940 回答
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;
}
于 2013-03-04T20:58:20.747 回答
5

你用的是什么源代码控制系统?

几乎所有这些都具有某种形式的 $Id $ 标签,当文件被签入时会被扩展。

我通常使用某种形式的hackery 将其显示为版本号。

另一种选择是使用日期作为内部版本号:080803-1448

于 2008-08-03T18:46:33.517 回答
5

[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"为执行任务)时,将触发刷新代码以计算新版本号,并且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 客户端的地方(请记住通过调用nuget SetApiKey <my-api-key>或在 NuGet 推送调用中包含该密钥来保存您的 NuGet API 密钥)。

以防万一它对某人有所帮助^_^。

于 2017-05-10T14:08:29.120 回答
1

前段时间我写了一个快速而肮脏的 exe,它会更新 assemblyinfo.{cs/vb} 中的版本号 - 我还使用 rxfind.exe(一个简单而强大的基于正则表达式的搜索替换工具)来做作为构建过程的一部分,从命令行进行更新。其他一些有用的提示:

  1. 将组件信息分成产品部分(公司名称、版本等)和组件特定部分(组件名称等)。看这里
  2. 另外 - 我使用 subversion,所以我发现将内部版本号设置为 subversion 修订号很有帮助,从而可以很容易地始终返回生成程序集的代码库(例如 1.4.100.1502 是从修订版 1502 构建的)。
于 2008-08-04T19:51:49.610 回答
0

如果您想要一个在每次编译完成时更新的自动递增数字,您可以使用预构建事件中的VersionUpdater 。如果您愿意,您的预构建事件可以检查构建配置,以便版本号只会在发布构建时增加(例如)。

于 2010-02-28T21:16:35.570 回答
0

这是一个手动替代选项:这是我编写的一个快速而肮脏的 PowerShell 片段,它在我们的 Jenkins 构建系统的预构建步骤中被调用。

AssemblyVersion它将and的最后一位数字设置为由构建系统自动设置AssemblyFileVersion的环境变量的值。BUILD_NUMBER

if (Test-Path env:BUILD_NUMBER) {
    Write-Host "Updating AssemblyVersion to $env:BUILD_NUMBER"

    # Get the AssemblyInfo.cs
    $assemblyInfo = Get-Content -Path .\MyShinyApplication\Properties\AssemblyInfo.cs

    # Replace last digit of AssemblyVersion
    $assemblyInfo = $assemblyInfo -replace 
        "^\[assembly: AssemblyVersion\(`"([0-9]+)\.([0-9]+)\.([0-9]+)\.[0-9]+`"\)]", 
        ('[assembly: AssemblyVersion("$1.$2.$3.' + $env:BUILD_NUMBER + '")]')
    Write-Host  ($assemblyInfo -match '^\[assembly: AssemblyVersion')
        
    # Replace last digit of AssemblyFileVersion
    $assemblyInfo = $assemblyInfo -replace 
        "^\[assembly: AssemblyFileVersion\(`"([0-9]+)\.([0-9]+)\.([0-9]+)\.[0-9]+`"\)]", 
        ('[assembly: AssemblyFileVersion("$1.$2.$3.' + $env:BUILD_NUMBER + '")]')
    Write-Host  ($assemblyInfo -match '^\[assembly: AssemblyFileVersion')
        
    $assemblyInfo | Set-Content -Path .\MyShinyApplication\Properties\AssemblyInfo.cs -Encoding UTF8
} else {
    Write-Warning "BUILD_NUMBER is not set."
}
于 2021-04-19T16:31:55.373 回答