如何仅在程序集发生更改时才使用MSBuild更新版本信息?

我需要在同一个虚拟文件夹中安装多个Web安装项目(使用VS2005和ASP.Net/C#)。 这些项目共享一些程序集引用(文件系统都被构造为使用相同的“bin”文件夹),这使得对这些程序集的更改部署成为问题,因为如果当前安装的版本早于版本中的版本,则MS安装程序将仅覆盖程序集。 MSI。

我并不是说悲观的安装方案是错误的 – 只是它在我给予的环境中产生了一个问题。 由于有相当数量的通用程序集和大量开发人员可能会更改常见程序集但忘记更新其版本号,因此尝试手动管理版本控制最终会导致安装时出现大量混淆。

在这个问题的另一面,同样重要的是不要自发更新版本号并用每次安装替换所有通用程序集,因为这可能(暂时至少)模糊实际更改的情况。

也就是说,我正在寻找的是只有在程序集成分(代码模块,资源等)实际已经发生变化的情况下才更新程序集版本信息(最好使用MSBuild)的方法。

我在这里找到了一些至少部分相关的参考文献(MSDN上的AssemblyInfo任务)和这里 (看起来类似于我需要的,但超过两年,没有明确的解决方案)。

我的团队也使用TFS版本控制,因此自动化解决方案应该包括在构建期间可以检出/输入AssebmlyInfo的方法。

任何帮助将非常感激。

提前致谢。

我无法回答你的所有问题,因为我没有TFS的经验。

但我建议使用更好的方法来更新AssemblyInfo.cs文件,而不是使用AssemblyInfo任务。 该任务似乎只是从头开始重新创建标准AssemblyInfo文件,并丢失您可能添加的任何自定义部分。

因此,我建议您从MSBuild社区任务项目中查看FileUpdate任务。 它可以在文件中查找特定内容并替换它,如下所示:

 

有几种方法可以控制内部版本号的增量。 因为我只想在构建完全成功时增加构建号,所以我使用两步法:

  • 从文本文件中读取一个数字(文件中唯一的内容是数字)并在不更改文件的情况下添加1;
  • 作为构建过程的最后一步,如果一切都成功,将增加的数字保存回文本文件。

有一些任务,如ReadLinesFromFile,可以帮助你解决这个问题,但我发现编写一个小的自定义任务最简单:

 using System; using System.IO; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; namespace CredibleCustomBuildTasks { public class IncrementTask : Task { [Required] public bool SaveChange { get; set; } [Required] public string IncrementFileName { get; set; } [Output] public int Increment { get; set; } public override bool Execute() { if (File.Exists(IncrementFileName)) { string lines = File.ReadAllText(IncrementFileName); int result; if(Int32.TryParse(lines, out result)) { Increment = result + 1; } else { Log.LogError("Unable to parse integer in '{0}' (contents of {1})"); return false; } } else { Increment = 1; } if (SaveChange) { File.Delete(IncrementFileName); File.WriteAllText(IncrementFileName, Increment.ToString()); } return true; } } } 

我在FileUpdateTask之前使用它来获取下一个构建号:

    

并且作为我在构建中的最后一步(在通知其他人之前):

  

关于如何仅在源代码更改时更新版本号的另一个问题在很大程度上取决于构建过程与源代码控制的交互方式。 通常,检入源文件更改应启动持续集成构建。 这是用于更新相关版本号的那个。

我写了一个客户任务,你可以参考下面的代码。 它将创建一个实用程序,您可以将assemblyinfo路径传递给Major,minor和build number。 你可以修改它以获得修订号。 因为在我的情况下,这个任务是由开发人员完成的,我用来搜索它并再次替换整个字符串。

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Text.RegularExpressions; namespace UpdateVersion { class SetVersion { static void Main(string[] args) { String FilePath = args[0]; String MajVersion=args[1]; String MinVersion = args[2]; String BuildNumber = args[3]; string RevisionNumber = null; StreamReader Reader = File.OpenText(FilePath); string contents = Reader.ReadToEnd(); Reader.Close(); MatchCollection match = Regex.Matches(contents, @"\[assembly: AssemblyVersion\("".*""\)\]", RegexOptions.IgnoreCase); if (match[0].Value != null) { string strRevisionNumber = match[0].Value; RevisionNumber = strRevisionNumber.Substring(strRevisionNumber.LastIndexOf(".") + 1, (strRevisionNumber.LastIndexOf("\"")-1) - strRevisionNumber.LastIndexOf(".")); String replaceWithText = String.Format("[assembly: AssemblyVersion(\"{0}.{1}.{2}.{3}\")]", MajVersion, MinVersion, BuildNumber, RevisionNumber); string newText = Regex.Replace(contents, @"\[assembly: AssemblyVersion\("".*""\)\]", replaceWithText); StreamWriter writer = new StreamWriter(FilePath, false); writer.Write(newText); writer.Close(); } else { Console.WriteLine("No matching values found"); } } } } 

我讨厌这样说,但似乎你错了。 如果你动态生成汇编版本而不是试图修补它们会容易得多。

看看https://sbarnea.com/articles/easy-windows-build-versioning/

为什么我认为你做错了? *构建不应该修改版本号*如果您构建相同的变更集两次,您应该获得相同的构建号*如果您将构建号放在微软调用构建号内(正确命名将是PATCH级别),您最终将达到65535局限性。