如何在MSBuild中自动递增程序集或程序集文件版本?

3

限制条件如下: 使用Visual Studio 2017。 最终需要从调用MSBuild的PowerShell脚本中调用。

不确定是否相关,但需要能够构建以下内容:

  • asp.net 461
  • asp.net-core 1.1和2.0程序集

到目前为止尝试无果:

尝试示例 "构建过程中的代码生成",在VS构建过程中可用但不适用于MSBuild:

放置在项目根目录下的 handleVersioning.tt 文件:

<#@ template language="C#" #>

using System.Reflection;

[assembly: AssemblyVersion("1.0.0.*")]
[assembly: AssemblyFileVersion("<#= this.Year #>.<#= this.Month #>.<#= this.Day #>.<#= this.Minute #>")]
<#+
    int Year = DateTime.UtcNow.Year;
    int Month = DateTime.UtcNow.Month;
    int Day = DateTime.UtcNow.Day;
    int Minute = unchecked((int)DateTime.UtcNow.TimeOfDay.TotalMinutes);
#>

.csproj:

<Import Project="...hardcoded...\Microsoft.CSharp.targets" />
<!-- This is the important line: -->  
<Import Project="...hardcoded...\TextTemplating\Microsoft.TextTemplating.targets" />

<PropertyGroup>  
    <TransformOnBuild>true</TransformOnBuild>  
    <OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
    <TransformOutOfDateOnly>false</TransformOutOfDateOnly>
</PropertyGroup> 

调用方式如下: msbuild myProject.csproj /t:TransformAll


你有意标记了 "asp.net-core" 吗?如果你正在使用 asp.net core,那么你已经拥有一个项目系统,可以基于 msbuild 值生成程序集信息文件,这些值可以通过命令行传递或从项目文件中的日期和时间计算得出。 - Martin Ullrich
它需要能够构建asp.net 461程序集以及asp.net-core 1.1和2.0。我之前已经从标题中删除了asp.net-core,也将删除标签。 - ttugates
所以你的asp.net core项目已经支持了这个功能 - msbuild /p:Version=1.2.3.4 将设置程序集版本,我建议基于sdk-based projects的现有源代码为传统项目创建“polyfill targets”。现在没有时间做,但也许在接下来的几天里可以完成。然后就会像 https://dev59.com/ElgQ5IYBdhLWcg3wIAWb 一样运行。 - Martin Ullrich
@Zam - 最终我使用了 T4 模板解决了这个问题。话说,VS2017 社区版附带的任何版本的 MSBuild 也可以解决这个问题。我相信它是 C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe - 我稍后会将我的解决方案作为答案提供。对于 .Net 461.Net Core,它们是不同的,我现在已经迁移到了只用 .Net Core - ttugates
当我使用参数 /p:Version=1.2.3.4 运行 msbuild 时,版本仍然保持不变。我还在寻找我做错了什么。T4 - 是的,它工作得很好,但每次我需要重新保存这个文件。 - Zam
显示剩余3条评论
1个回答

0

您可以编写简单的控制台应用程序,在项目属性中>生成事件中,添加一个“预生成事件命令行”,如下所示:“D:\SomePath\MyAssemblyInfoPatcher.exe”“$(ProjectDir)Properties\AssemblyInfo.cs”

示例应用程序代码(适用于VS 2022)

using System;
using System.IO;
using System.Linq;

namespace MyAssemblyInfoPatcher
{
    internal class Program
    {
        static void Main(string[] args)
        {
            if (args.Length > 0)
            {
                string path = args[0].ToString();
                Console.WriteLine(string.Format("Current App version is set to: {0}", path));
                string now_date = DateTime.Now.ToString("yyyy.MM.dd.HHmm");
                if (File.Exists(path))
                {
                    string _AssemblyVersion = string.Empty;
                    string _AssemblyFileVersion = string.Empty;

                    var lines = File.ReadLines(string.Format(path));
                    for (int i = 0; i < lines.Count(); i++)
                    {
                        if (lines.ElementAt(i).ToString().StartsWith("[assembly: AssemblyVersion"))
                        {
                            _AssemblyVersion = lines.ElementAt(i).ToString();
                        }
                        else if (lines.ElementAt(i).ToString().StartsWith("[assembly: AssemblyFileVersion"))
                        {
                            _AssemblyFileVersion = lines.ElementAt(i).ToString();
                        }
                    }

                    string _replace_assembly = File.ReadAllText(path);

                    if (_AssemblyVersion != string.Empty)
                    {
                        _replace_assembly = _replace_assembly.Replace(_AssemblyVersion, string.Format("[assembly: AssemblyVersion(\"{0}\")]", now_date));
                    }
                    if (_AssemblyFileVersion != string.Empty)
                    {
                        _replace_assembly = _replace_assembly.Replace(_AssemblyFileVersion, string.Format("[assembly: AssemblyFileVersion(\"{0}\")]", now_date));
                    }

                    File.WriteAllText(path, _replace_assembly);
                }
            }   
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接