问答中心分类: C#如何拥有自动递增的版本号(Visual Studio)?[副本]
0
Matthieu 提问 1月 前

这个问题在这里已经有答案了:

使用Visual Studio时,是否可以自动增加文件生成版本?
(25个答案)

关闭8年前.

我想存储一组在构建时自动递增的整数:

int MajorVersion = 0;
int MinorVersion = 1;
int Revision = 92;

当我编译时,它会自动递增Revision. 当我构建安装项目时,它会增加MinorVersion(我可以手动执行此操作)。MajorVersion只能手动递增。
然后,我可以在“帮助/关于”菜单中向用户显示版本号,如下所示:

版本:0.1.92

如何做到这一点?
这个问题不仅要问如何拥有一个自动递增的版本号,还要问如何在代码中使用这个版本号,这是一个比其他版本更完整的答案。

8 Answers
0
Matthieu 回答 1月 前

您可以使用Visual Studio中的T4模板机制,用于从简单文本文件生成所需的源代码:

我想为一些配置版本信息生成。净额
灵感来自StackOverflow的一次讨论,其中

  1. 创建一个扩展名为“.tt”的文件,并将T4模板放在那里,该模板将生成AssemblyVersion和AssemblyFileVersion属性:
<#@ template language="C#" #>
// 
// This code was generated by a tool. Any changes made manually will be lost
// the next time this code is regenerated.
// 

using System.Reflection;

[assembly: AssemblyVersion("1.0.1.<#= this.RevisionNumber #>")]
[assembly: AssemblyFileVersion("1.0.1.<#= this.RevisionNumber #>")]
<#+
    int RevisionNumber = (int)(DateTime.UtcNow - new DateTime(2010,1,1)).TotalDays;
#>

您必须决定版本号生成算法。对于

  1. 上述文件应放置在其中一个项目中。我用这个文件创建了一个新项目来进行版本管理
// 
// This code was generated by a tool. Any changes made manually will be lost
// the next time this code is regenerated.
// 

using System.Reflection;

[assembly: AssemblyVersion("1.0.1.113")]
[assembly: AssemblyFileVersion("1.0.1.113")]

是的,今天距离2010年1月1日已经113天了。明天

  1. 下一步是从AssemblyInfo中删除AssemblyVersion和AssemblyFileVersion属性。所有项目中的cs文件

我喜欢这种方法的地方在于它是轻量级的(无需定制

Adam Nofsinger 回复 1月 前

我认为这是一个很好的解决方案,因为它具有插件和自定义可执行文件的灵活性,但它是一个纯现成的Visual Studio解决方案。

CoderTao 回复 1月 前

很好地满足了我的需要,使用bzr revno填充了部分版本信息

Kelly Adams 回复 1月 前

这对于为JS和CSS引用生成特定于构建的缓存破坏令牌也非常有用。

hakan 回复 1月 前

我不明白这个解决方案。。。我们必须调用TransformText()方法来获取结果文件。。。

Gunnar 回复 1月 前

我同意piedpiper的观点。是否缺少一个步骤?创建了一个c#文件,但与上面显示的完全不同。共有331行代码,其中一个突出的功能是:public virtual string TransformText()

Ben Philipp 回复 1月 前

在我看来是这样的只有生成每日更改的修订号。对我来说听起来不太中肯。。。我甚至不会每天都在做我的项目。另一方面,有时我会重做整个部分,值得做一些小的和大的更新。我错过了什么吗?或者这只是一个“每日修订”标签?

Andrey Moiseev 回复 1月 前

@Gunnar Via管道Add New Item在项目的上下文菜单中,创建Text Template,而不是Runtime Text Template.

Andrey Moiseev 回复 1月 前

此外,仅当模板更改时,才会渲染这些模板。这仅适用于AutoT4 Visual Studio Extension或类似的功能。

ttugates 回复 1月 前

使用此解决方案,使用MSBuild从cmd生成不会增加版本控制/运行T4。

ttugates 回复 1月 前

我已经创建了这个如何从MSBuild自动递增程序集或程序集文件版本并感谢您的帮助。

Peter 回复 1月 前

我刚刚安装了AutoT4 Visual studio extension,但这个答案不起作用,缺少哪些步骤?。

Peter 回复 1月 前

它不会更新AssemblyInfo。但它确实更新了编译版本。txt(tt文件的名称也是这样,但width.cs)

Developer63 回复 1月 前

我一直在寻找尝试T4模板并将其添加到我的技能集中的原因,而这个答案绝对是让我开始学习的入门药物!谢谢你,马修·弗兰肯斯坦博士!爱,怪物

0
Drew Chapin 回答 1月 前

这是我对T4建议的实施。。。这将在每次生成项目时增加版本号,而不管选择的配置如何(即调试|版本),并且在每次执行版本生成时增加版本号。您可以通过以下方式继续更新主要版本号和次要版本号应用➤ 程序集信息。。。
要更详细地解释,请阅读现有AssemblyInfo.cs文件,并使用regex查找AssemblyVersion信息,然后根据TextTransform.exe.

  1. 删除现有的AssemblyInfo.cs文件
  2. 创建AssemblyInfo.tt文件就位。Visual Studio应创建AssemblyInfo.cs并在保存T4文件后将其与T4文件分组。
    <#@ template debug="true" hostspecific="true" language="C#" #>
    <#@ output extension=".cs" #>
    <#@ import namespace="System.IO" #>
    <#@ import namespace="System.Text.RegularExpressions" #>
    <#
        string output = File.ReadAllText(this.Host.ResolvePath("AssemblyInfo.cs"));
        Regex pattern = new Regex("AssemblyVersion\\(\"(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<revision>\\d+)\\.(?<build>\\d+)\"\\)");
        MatchCollection matches = pattern.Matches(output);
        if( matches.Count == 1 )
        {
            major = Convert.ToInt32(matches[0].Groups["major"].Value);
            minor = Convert.ToInt32(matches[0].Groups["minor"].Value);
            build = Convert.ToInt32(matches[0].Groups["build"].Value) + 1;
            revision = Convert.ToInt32(matches[0].Groups["revision"].Value);
            if( this.Host.ResolveParameterValue("-","-","BuildConfiguration") == "Release" )
                revision++;
        }
    #>
    
    using System.Reflection;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using System.Resources;
    
    // General Information
    [assembly: AssemblyTitle("Insert title here")]
    [assembly: AssemblyDescription("Insert description here")]
    [assembly: AssemblyConfiguration("")]
    [assembly: AssemblyCompany("Insert company here")]
    [assembly: AssemblyProduct("Insert product here")]
    [assembly: AssemblyCopyright("Insert copyright here")]
    [assembly: AssemblyTrademark("Insert trademark here")]
    [assembly: AssemblyCulture("")]
    
    // Version informationr(
    [assembly: AssemblyVersion("<#= this.major #>.<#= this.minor #>.<#= this.revision #>.<#= this.build #>")]
    [assembly: AssemblyFileVersion("<#= this.major #>.<#= this.minor #>.<#= this.revision #>.<#= this.build #>")]
    [assembly: NeutralResourcesLanguageAttribute( "en-US" )]
    
    <#+
        int major = 1;
        int minor = 0;
        int revision = 0;
        int build = 0;
    #>
  3. 将此添加到预构建事件中:
    "%CommonProgramFiles(x86)%\microsoft shared\TextTemplating$(VisualStudioVersion)\TextTransform.exe" -a !!BuildConfiguration!$(Configuration) "$(ProjectDir)Properties\AssemblyInfo.tt"
Tanya 回复 1月 前

是否可以覆盖少数程序集中的版本号?

Drew Chapin 回复 1月 前

@Tanya,是的,编辑一下AssemblyInfo.cs在生成之前手动归档。输入一个小于所需值的数字1。所以如果你想5,然后输入4.

BurnsBA 回复 1月 前

而不是10您可以引用当前Visual Studio版本作为变量:"%CommonProgramFiles(x86)%\microsoft shared\TextTemplating\$(VisualStudioVersion)\TextTransform.exe" -a !!build!true "$(ProjectDir)Properties\AssemblyInfo.tt"

Drew Chapin 回复 1月 前

@伯恩斯巴,谢谢你的建议!我改变了答案以反映这一点。

Zam 回复 1月 前

预构建活动非常重要!非常感谢。一旦我这样做了,每次我从VS2017或通过控制台构建项目时,我的版本号都会更新。

Barry 回复 1月 前

仅供参考如果要将此打包到Nuget包中,请确保并更改的构建操作。tt文件(属性)为无。这样,当最终用户应用程序利用您的Nuget包时,它不会注入您的AssemblyInfo。tt文件输入到他们的项目中。

raiserle 回复 1月 前

对于2017社区版,我已将预构建活动更改为:"c:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\TextTransform.exe" "$(ProjectDir)Properties\AssemblyInfo.tt"这对我来说很好。当做

Jahmic 回复 1月 前

至少在VS 2017中,您甚至不需要设置手动预构建命令。它将自动运行。

Brains 回复 1月 前

"$(DevEnvDir)TextTransform.exe"可用于代替"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\TextTransform.exe"

Venkat 回复 1月 前

@DrewChapin:如何将多个参数传递给TextTransform。exe是否使用“a”选项?

Mecanik 回复 1月 前

这是一个很好的解决方案,但是您已经将构建和修订位置搞砸了。VS明确表示:主要。少数的建筑修订,所以您必须交换修订并在模板中生成。1、新正则表达式(“AssemblyVersion \(\”(?\\d+\\。(?\\d+\\。(?\\d+\\。(?\\d+“\”);2.[程序集:AssemblyVersion(“…”)]3.[程序集:AssemblyFileVersion(“…”)]

0
gideon 回答 1月 前

如果在内部版本和修订版中添加星号,visual studio将使用自2000年1月1日起的天数作为内部版本号,使用自午夜起的秒数除以2作为修订版。
更好的救生解决方案是http://autobuildversion.codeplex.com/
它很有魅力,而且非常灵活。

hakan 回复 1月 前

VS2013不起作用。

m1m1k 回复 1月 前

感谢您的解释-我试图弄清楚为什么在没有查看版本号的情况下,版本号没有增加(在同一天)。这就解释了,谢谢你。

0
galets 回答 1月 前

这是在AssemblyInfo上引用。来自MSDN的cs:

可以指定所有值,也可以). 例如“)]

这实际上是说,如果你把1.1。*在程序集信息中,只有内部版本号会自动递增,并且不会在每次内部版本后自动递增,而是每天自动递增。修订号将更改每个版本,但是随机的,而不是以递增的方式。
对于大多数用例来说,这可能已经足够了。如果这不是您想要的,那么您必须编写一个脚本,在预构建步骤中自动增加版本

Ian Boyd 回复 1月 前

它随机递增?他们在开玩笑吗?

Ronnie Overby 回复 1月 前

根据msdn。微软com/en-us/library/…修订号不是随机的,而是从上午12点开始的秒数除以2,在我看来,这还不错。

maxkoryukov 回复 1月 前

塞姆弗标准但微软一如既往地有自己的.

d219 回复 1月 前

默认修订号不是随机的-在您提供的链接中,它表示“默认修订号是当地时间午夜后的秒数(不考虑夏令时的时区调整),除以2。”

0
Micah Smith 回答 1月 前

使用AssemblyInfo。反恐精英
在App\u代码中创建文件:并填写以下内容,或使用谷歌搜索其他属性/属性。
AssemblyInfo。反恐精英

using System.Reflection;

[assembly: AssemblyDescription("Very useful stuff here.")]
[assembly: AssemblyCompany("companyname")]
[assembly: AssemblyCopyright("Copyright © me 2009")]
[assembly: AssemblyProduct("NeatProduct")]
[assembly: AssemblyVersion("1.1.*")]

AssemblyVersion是您真正想要的部件。
然后,如果您正在网站、任何aspx页面或控件中工作,您可以在标签中添加以下内容:

CompilerOptions="<folderpath>\App_Code\AssemblyInfo.cs"

(当然,用适当的变量替换folderpath)。
我认为您不需要以任何方式为其他类添加编译器选项;App\U代码中的所有版本在编译时都应该收到版本信息。
希望这有帮助。