自定义MSBuild任务无法设置C#项目Assembly Version,求修改建议
如何通过自定义MSBuild任务设置C#项目的Assembly Version?
你想要通过自定义MSBuild任务生成符合规则的Assembly Version:主版本固定为3,次版本0,构建号是年份+日历周,修订号是当前星期几,但目前的代码没能正常工作,我来帮你梳理问题并给出修改方案:
问题分析与修改点
任务执行时机错误
你把目标TestBuild设置为AfterTargets="Build",这时候项目已经完成编译了,生成的版本号根本没机会应用到程序集上。必须把任务放在编译前执行,比如绑定到CoreCompile或者GenerateAssemblyInfo之前。日历周格式补零
GetWeekOfYear返回的是1-53的数字,比如第5周会返回5,直接拼接的话版本号会是3.0.245.1,这会导致版本排序异常(比如第10周会变成3.0.2410.1,比3.0.245.1小),需要给周数补前导零,变成两位数字。星期几的数值调整(可选)
.NET的DayOfWeek枚举中,周日是0,周一到周六是1-6。如果你的需求里星期几是从1(周一)到7(周日),那需要把0转换成7,否则修订号会出现0,不符合常规版本号的使用习惯。缺少版本号的应用步骤
你只是获取了AssemblyVersion属性,但没有把它应用到项目中。对于SDK风格的项目,直接设置项目属性即可;旧项目则需要更新AssemblyInfo.cs文件。
修改后的完整代码
1. 自定义任务部分(修复周数补零和星期几处理)
<UsingTask TaskName="DetectAssemblyVersion" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll"> <ParameterGroup> <Result ParameterType="System.String" Output="true" /> </ParameterGroup> <Task> <Code Type="Fragment" Language="cs"> <![CDATA[ var now = System.DateTime.Now; // 获取两位年份(比如2024→24) string year = now.ToString("yy"); // 获取日历周,补前导零为两位 var dfi = System.Globalization.DateTimeFormatInfo.CurrentInfo; var cal = dfi.Calendar; int weekNum = cal.GetWeekOfYear(now, dfi.CalendarWeekRule, dfi.FirstDayOfWeek); string calendarWeek = weekNum.ToString("D2"); // 处理星期几:周日转7,其余保持1-6 int dayOfWeek = (int)now.DayOfWeek; dayOfWeek = dayOfWeek == 0 ? 7 : dayOfWeek; Result = $"3.0.{year}{calendarWeek}.{dayOfWeek}"; Log.LogMessage(MessageImportance.High, "Detected current version: " + Result); ]]> </Code> </Task> </UsingTask>
2. 目标任务部分(调整执行时机并应用版本号)
如果是SDK风格项目(.NET Core/.NET 5+),可以直接设置项目属性:
<Target Name="SetAssemblyVersion" BeforeTargets="GenerateAssemblyInfo"> <DetectAssemblyVersion> <Output PropertyName="AssemblyVersion" TaskParameter="Result" /> </DetectAssemblyVersion> <!-- 同时设置FileVersion保持一致,可选 --> <PropertyGroup> <FileVersion>$(AssemblyVersion)</FileVersion> </PropertyGroup> <Message Importance="High" Text="New version applied: $(AssemblyVersion)" /> </Target>
如果是旧版.NET Framework项目,需要更新AssemblyInfo.cs文件:
<Target Name="SetAssemblyVersion" BeforeTargets="CoreCompile"> <DetectAssemblyVersion> <Output PropertyName="AssemblyVersion" TaskParameter="Result" /> </DetectAssemblyVersion> <!-- 更新AssemblyInfo.cs中的版本号 --> <WriteLinesToFile File="Properties\AssemblyInfo.cs" Lines="using System.Reflection; [assembly: AssemblyVersion("$(AssemblyVersion)")] [assembly: AssemblyFileVersion("$(AssemblyVersion)")]" Overwrite="false" Encoding="UTF-8" /> <Message Importance="High" Text="New version applied to AssemblyInfo: $(AssemblyVersion)" /> </Target>
额外说明
- 如果你需要四位年份(比如2024而不是24),把
year = now.ToString("yy")改成year = now.ToString("yyyy")即可。 - 确认
MSBuildToolsPath指向的路径正确,对于.NET Framework项目,通常是C:\Program Files (x86)\MSBuild\14.0\Bin之类的路径,SDK项目会自动处理。
内容的提问来源于stack exchange,提问作者Gleees
相关产品推荐
相关产品推荐

