代码之家  ›  专栏  ›  技术社区  ›  esac

如何具有自动递增的版本号(Visual Studio)?[复制品]

  •  420
  • esac  · 技术社区  · 15 年前

    我要存储一组在生成时自动递增的整数:

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

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

    然后我可以在菜单帮助/关于中向用户显示版本号,如下所示:

      Version: 0.1.92
    

    如何实现这一目标?

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

    9 回复  |  直到 6 年前
        1
  •  558
  •   0xced    7 年前

    如果添加 AssemblyInfo 类并将assemblyversion属性修改为以星号结尾,例如:

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

    Visual Studio将根据 these rules (多谢盖尔斯,我完全错了!)

    要在代码中引用此版本,以便向用户显示它,可以使用反射。例如,

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

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

    从@ ASHES99:

    同样值得注意的是,如果两者都是 AssemblyVersion AssemblyFileVersion 如果指定了,则在.exe上看不到。

    来自@brainslugs83:

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

        2
  •  154
  •   Matthieu    9 年前

    你可以用 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 或生成过程自定义。这里应该做什么:

    1. 创建扩展名为“.tt”的文件,并将生成assemblyversion和assemblyfileversion属性的t4模板放在那里:
    <#@ 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编写的,因此您可以轻松地 根据需要进行调整。

    1. 上面的文件应该放在其中一个项目中。我用这个文件创建了一个新项目来进行版本管理 技术清晰。当我构建这个项目时(实际上我甚至不需要 构建它:保存文件足以触发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天。明天 修订号将更改。

    1. 下一步是从所有项目中的assemblyinfo.cs文件中移除assemblyversion和assemblyfileversion属性。 共享相同的自动生成的版本信息。选择__添加 现有项_157;对于每个项目,使用t4导航到文件夹 模板文件,选择相应的_.cs_文件并将其作为链接添加。 那就行了!

    我喜欢这种方法的原因是它很轻(没有定制 未将自动生成的版本信息添加到 源代码管理。当然,使用C生成版本 算法为任何复杂的算法打开。

        3
  •  41
  •   Drew Chapin    6 年前

    这是我对T4建议的实施…这将在每次构建项目时增加内部版本号,而不考虑所选的配置(即调试版本),并且在每次进行发布构建时都会增加修订号。您可以通过以下方式继续更新主版本号和次版本号: 应用程序组装信息…

    为了更详细地解释,这将阅读现有的 AssemblyInfo.cs 文件,并使用regex查找 AssemblyVersion 信息,然后根据输入增加修订和构建编号 TextTransform.exe .

    1. 删除现有的 汇编语言 文件。
    2. 创建一个 AssemblyInfo.tt 文件在其位置。Visual Studio应创建 汇编语言 保存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"
      
        4
  •  31
  •   gideon    13 年前

    如果在for build and revision中输入星号,Visual Studio将使用2000年1月1日以来的天数作为生成编号,并将午夜以来的秒数除以2作为修订。

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

    它就像一个魅力,而且非常灵活。

        5
  •  23
  •   galets    15 年前

    这里是 quote on AssemblyInfo.cs from MSDN :

    您可以指定所有值,或者 可以接受默认的内部版本号, 修订号,或同时使用 星号(星号) )例如, [组件:组件版本(“2.3.25.1”)] 表示主版本为2,表示主版本为3 次要版本,25作为版本 编号,1作为修订号。 版本号,如 [组件:组件版本(“1.2. “” 指定1为主版本,2为 次要版本,并接受 默认版本号和修订号。一 版本号,如 [组件:组件版本(“1.2.15.*”)] 指定1为主版本,2为 次要版本,15作为版本 数字,并接受默认值 修订号。默认生成 数字每天递增。默认值 修订号是随机的

    这实际上意味着,如果将1.1.*放到程序集信息中,只有内部版本号将自动递增,并且它不会在每次生成之后发生,而是每天发生。修订号将改变每个构建,但是随机的,而不是以递增的方式。

    对于大多数用例来说,这可能已经足够了。如果这不是您要找的,那么您必须编写一个脚本,该脚本将在预构建步骤上自动增加版本。

        6
  •  14
  •   user7116    15 年前

    使用assemblyinfo.cs

    在app_code中创建文件:并填写以下内容或使用Google获取其他属性/属性。

    汇编语言

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

    我认为您不需要以任何方式为其他类添加编译器选项;应用程序代码中的所有类在编译时都应该收到版本信息。

    希望有帮助。

        7
  •  10
  •   Mun    11 年前

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

    由于应用程序是开放源码的,所以我还创建了一个版本来使用该格式增加版本号。 (主要版本)。(次要版本)。([年][年的第几天])(增量) . 有关此和修订代码的更多信息,请访问我的日志, Assembly Version Numbers and .NET .

    更新:我已经将更新版本应用程序的修改版本的代码放在GitHub上: https://github.com/munr/UpdateVersion

        8
  •  10
  •   Drew Chapin    7 年前
    • 星型版本(如“2.10.3.*”)—很简单,但数字太大

    • AutobuildVersion-看起来不错,但在我的VS2010上不起作用。

    • @Drewchapin的脚本可以工作,但是我不能在我的工作室中为调试预生成事件和发布预生成事件设置不同的模式。

    所以我把剧本改了一点… 联系人:

    "%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;
    #>
    
        9
  •  2
  •   Raymond    15 年前

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