首页 文章

如何获得自动递增版本号(Visual Studio)? [重复]

提问于
浏览
411

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

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

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

当我编译时,它将自动递增 Revision . 当我构建安装项目时,它将增加 MinorVersion (我可以手动执行此操作) . MajorVersion 只会手动递增 .

然后我可以在菜单Help / About中向用户显示版本号:

Version: 0.1.92

怎么能实现这一目标?

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

9 回答

  • 150

    如果将AssemblyInfo类添加到项目中并将AssemblyVersion属性修改为以星号结尾,例如:

    [assembly: AssemblyVersion("2.10.*")]
    

    Visual Studio将根据these rules为您增加最终数字(感谢galets,我完全错了!)

    要在代码中引用此版本,以便可以将其显示给用户,请使用反射 . 例如,

    Version version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
    DateTime buildDate = new DateTime(2000, 1, 1)
                            .AddDays(version.Build).AddSeconds(version.Revision * 2);
    string displayableVersion = $"{version} ({buildDate})";
    

    你应该知道的两个重要问题

    来自@ ashes999:

    同样值得注意的是,如果同时指定 AssemblyVersionAssemblyFileVersion ,则不会在.exe上看到此内容 .

    来自@ BrainSlugs83:

    仅将第4个数字设置为 * 可能不好,因为版本不会总是递增 . 第3个数字是自2000年以来的天数,第4个数字是自午夜以来的秒数(除以2)[不是随机数] . 因此,如果您在一天的最后一天和第二天的早些时候构建解决方案,则后一版本将具有较早的版本号 . 我建议始终使用 X.Y.* 而不是 X.Y.Z.* ,因为您的版本号将始终以这种方式增加 .

  • 37

    如果您在构建和修订中添加星号,则visual studio将使用自2000年1月1日以来的天数作为内部版本号,并将自午夜以来的秒数除以2作为修订版 .

    一个更好的救生解决方案是http://autobuildversion.codeplex.com/

    它就像一个魅力,它非常灵活 .

  • 10
    • 版本中的星标(如“2.10.3 . *”) - 它很简单,但数字太大了

    • AutoBuildVersion - 看起来很棒,但它不适用于我的VS2010 .

    • @DrewChapin的脚本有效,但我不能在我的工作室中为Debug预构建事件和Release预构建事件设置不同的模式 .

    所以我改了一下脚本...... commamd:

    "%CommonProgramFiles(x86)%\microsoft shared\TextTemplating\10.0\TextTransform.exe" -a !!$(ConfigurationName)!1 "$(ProjectDir)Properties\AssemblyInfo.tt"
    

    和脚本(这适用于“调试”和“发布”配置):

    <#@ template debug="true" hostspecific="true" language="C#" #>
    <#@ output extension=".cs" #>
    <#@ assembly name="System.Windows.Forms" #>
    <#@ import namespace="System.IO" #>
    <#@ import namespace="System.Text.RegularExpressions" #>
    <#
        int incRevision = 1;
        int incBuild = 1;
    
        try { incRevision = Convert.ToInt32(this.Host.ResolveParameterValue("","","Debug"));} catch( Exception ) { incBuild=0; }
        try { incBuild = Convert.ToInt32(this.Host.ResolveParameterValue("","","Release")); } catch( Exception ) { incRevision=0; }
        try {
            string currentDirectory = Path.GetDirectoryName(Host.TemplateFile);
            string assemblyInfo = File.ReadAllText(Path.Combine(currentDirectory,"AssemblyInfo.cs"));
            Regex pattern = new Regex("AssemblyVersion\\(\"\\d+\\.\\d+\\.(?<revision>\\d+)\\.(?<build>\\d+)\"\\)");
            MatchCollection matches = pattern.Matches(assemblyInfo);
            revision = Convert.ToInt32(matches[0].Groups["revision"].Value) + incRevision;
            build = Convert.ToInt32(matches[0].Groups["build"].Value) + incBuild;
        }
        catch( Exception ) { }
    #>
    using System.Reflection;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    
    // General Information about an assembly is controlled through the following
    // set of attributes. Change these attribute values to modify the information
    // associated with an assembly.
    [assembly: AssemblyTitle("Game engine. Keys: F2 (Debug trace), F4 (Fullscreen), Shift+Arrows (Move view). ")]
    [assembly: AssemblyProduct("Game engine")]
    [assembly: AssemblyDescription("My engine for game")]
    [assembly: AssemblyCompany("")]
    [assembly: AssemblyCopyright("Copyright © Name 2013")]
    [assembly: AssemblyTrademark("")]
    [assembly: AssemblyCulture("")]
    
    // Setting ComVisible to false makes the types in this assembly not visible
    // to COM components.  If you need to access a type in this assembly from
    // COM, set the ComVisible attribute to true on that type. Only Windows
    // assemblies support COM.
    [assembly: ComVisible(false)]
    
    // On Windows, the following GUID is for the ID of the typelib if this
    // project is exposed to COM. On other platforms, it unique identifies the
    // title storage container when deploying this assembly to the device.
    [assembly: Guid("00000000-0000-0000-0000-000000000000")]
    
    // Version information for an assembly consists of the following four values:
    //
    //      Major Version
    //      Minor Version
    //      Build Number
    //      Revision
    //
    [assembly: AssemblyVersion("0.1.<#= this.revision #>.<#= this.build #>")]
    [assembly: AssemblyFileVersion("0.1.<#= this.revision #>.<#= this.build #>")]
    
    <#+
        int revision = 0;
        int build = 0;
    #>
    
  • 2

    Here's the quote on AssemblyInfo.cs from MSDN:

    您可以指定所有值,也可以使用星号()接受默认的内部版本号,修订号或两者 . 例如,[assembly:AssemblyVersion(“2.3.25.1”)]表示2为主要版本,3表示次要版本,25表示构建号,1表示版本号 . 诸如[assembly:AssemblyVersion(“1.2 . ”)]之类的版本号指定1为主要版本,2为次要版本,并接受默认的构建和修订号 . 诸如[assembly:AssemblyVersion(“1.2.15 . *”)]之类的版本号指定1作为主要版本,2作为次要版本,15作为构建号,并接受默认修订号 . 默认构建号每天递增 . 默认修订号是随机的

    这有效地说,如果你将1.1 . *放入汇编信息中,只有内部编号会自动增加,并且不会在每次构建之后发生,而是每天都会发生 . 修订号将改变每个构建,但是随机地,而不是以递增的方式 .

    对于大多数用例来说,这可能就足够了 . 如果这不是您正在寻找的东西,那么您将不得不编写一个脚本,该脚本会在预构建步骤中自动增加版本#

  • 23

    使用AssemblyInfo.cs

    在App_Code中创建文件:并填写以下内容或使用Google获取其他属性/属性的可能性 .

    AssemblyInfo.cs

    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页面或控件,您可以添加<Page>标记,如下所示:

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

    (当然用适当的变量替换folderpath) .

    我不认为你需要以任何方式为其他类添加编译器选项; App_Code中的所有内容在编译时都应该收到版本信息 .

    希望有所帮助 .

  • 541

    您可以使用构建脚本(例如Build Versioning)执行更高级的版本控制

  • 31

    你可以使用T4 templating mechanism in Visual Studio to generate the required source code from a simple text file

    我想为某些.NET项目配置版本信息生成 . 自从我研究了可用的选项以来已经很长时间了,所以我一直在搜索,希望能找到一些简单的方法 . 我发现的内容并不令人鼓舞:人们编写Visual Studio加载项和自定义MsBuild任务只是为了获得一个整数(好吧,也许两个) . 对于一个小型的个人项目来说,这感觉有些过分 . 灵感来自StackOverflow讨论之一,其中有人建议使用T4模板可以做这个工作 . 他们当然可以 . 该解决方案需要最少的工作量,并且不需要Visual Studio或构建流程定制 . 这里应该做什么:创建一个扩展名为“.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;
    #>
    

    您必须决定版本号生成算法 . 对我来说,自动生成一个修订号就足够了,该修订号设置为自2010年1月1日以来的天数 . 正如您所看到的,版本生成规则是用简单的C#编写的,因此您可以根据需要轻松调整它 . 上面的文件应该放在其中一个项目中 . 我用这个单独的文件创建了一个新项目,以使版本管理技术变得清晰 . 当我构建这个项目时(实际上我甚至不需要构建它:保存文件足以触发Visual Studio操作),生成以下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.113")]
    [assembly: AssemblyFileVersion("1.0.1.113")]
    

    是的,今天是自2010年1月1日起的113天 . 明天修订号将会改变 . 下一步是从应共享相同自动生成的版本信息的所有项目中的AssemblyInfo.cs文件中删除AssemblyVersion和AssemblyFileVersion属性 . 而是为每个项目选择“添加现有项目”,导航到包含T4模板文件的文件夹,选择相应的“.cs”文件并将其添加为链接 . 那会的!我喜欢这种方法的是它是轻量级的(没有自定义的MsBuild任务),并且自动生成的版本信息没有添加到源代码控制中 . 当然,使用C#版本生成算法可以打开任何复杂的算法 .

  • 14

    这是我对T4建议的实现...这将在每次构建项目时增加构建号,而不管所选的配置(即Debug | Release),并且每次执行Release构建时它都会增加修订号 . 您可以通过 Application ➤ Assembly Information... 继续更新主要和次要版本号

    为了更详细地解释,这将读取现有的 AssemblyInfo.cs 文件,并使用正则表达式查找 AssemblyVersion 信息,然后根据 TextTransform.exe 的输入增加修订版本和内部版本号 .

    • 删除现有的 AssemblyInfo.cs 文件 .

    • 在其位置创建 AssemblyInfo.tt 文件 . 保存T4文件后,Visual Studio应创建 AssemblyInfo.cs 并将其与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;
    #>
    
    • 将此添加到预构建事件:
    "%CommonProgramFiles(x86)%\microsoft shared\TextTemplating\$(VisualStudioVersion)\TextTransform.exe" -a !!BuildConfiguration!$(Configuration) "$(ProjectDir)Properties\AssemblyInfo.tt"
    
  • 10

    您可以尝试使用UpdateVersion by Matt Griffith . 现在已经很老了,但效果很好 . 要使用它,您只需要设置一个指向AssemblyInfo.cs文件的预构建事件,应用程序将根据命令行参数相应地更新版本号 .

    由于应用程序是开源的,我还创建了一个版本,使用格式(主要版本)增加版本号 . (次要版本) . ([year] [dayofyear]) . (增量) . 有关此内容和修订代码的更多信息,请参阅我的博客文章Assembly Version Numbers and .NET .

    Update: I've put the code for my modified version of the UpdateVersion application on GitHub: https://github.com/munr/UpdateVersion

相关问题