如何在CoreCompile阶段前获取自动生成的程序集构建版本号?
实现方案
完全可以在CoreCompile执行前拿到通配符生成的自动版本号,不存在时机过早的问题。
原理说明
当你使用[assembly: AssemblyVersion("1.0.*")]通配符格式定义版本时,SDK风格项目(.NET Core/.NET 5及以上版本)内置的GetAssemblyVersion构建目标会提前完成版本号计算,执行时机远早于核心编译步骤:
- 版本生成规则:第三段为当前日期距离2000年1月1日的总天数,第四段为当日已过去的总秒数除以2取整
- 计算完成后,完整版本号会写入
AssemblyVersion和FileVersion两个MSBuild属性中,后续编译、资源写入步骤都会直接读取这两个属性的值
正确写法
你只需要给自定义目标加上AfterTargets="GetAssemblyVersion"的配置,保证执行顺序在版本计算步骤之后,就可以直接读取生成好的版本号,示例如下:
<Target Name="MyNiceTarget" BeforeTargets="CoreCompile" AfterTargets="GetAssemblyVersion"> <PropertyGroup> <!-- 直接读取自动生成的文件版本号,格式为1.0.xxxx.xxxxx --> <GeneratedFileVersion>$(FileVersion)</GeneratedFileVersion> <!-- 拼接你需要的带自定义后缀的产品版本 --> <AssemblyInformationalVersion>$(GeneratedFileVersion)-mycomment</AssemblyInformationalVersion> </PropertyGroup> <!-- 其余自定义逻辑写在此处 --> </Target>
最终生成的二进制文件详情就会得到你预期的效果:
File version: 1.0.8218.27256 Product version: 1.0.8218.27256-mycomment
传统.NET Framework项目适配
如果是旧的非SDK风格.NET Framework项目,没有内置的GetAssemblyVersion目标,自动版本号默认由csc编译器在编译阶段生成,这种情况你可以在自定义目标里按官方规则自行计算版本号,写法如下:
<Target Name="MyNiceTarget" BeforeTargets="CoreCompile"> <PropertyGroup> <VersionPrefix>1.0</VersionPrefix> <!-- 计算和编译器完全一致的版本号 --> <BuildNumber>$([System.DateTime]::Now.Subtract($([System.DateTime]::new(2000,1,1))).TotalDays.ToString("F0"))</BuildNumber> <RevisionNumber>$([System.Math]::Floor($([System.DateTime]::Now.TimeOfDay.TotalSeconds / 2)).ToString("F0"))</RevisionNumber> <FileVersion>$(VersionPrefix).$(BuildNumber).$(RevisionNumber)</FileVersion> <AssemblyInformationalVersion>$(FileVersion)-mycomment</AssemblyInformationalVersion> </PropertyGroup> </Target>
注意事项
- 不要同时在项目文件(csproj/vbproj)中硬编码
AssemblyVersion或FileVersion属性,会覆盖通配符的自动生成逻辑 - 若你是在代码文件中写的
AssemblyVersion特性,建议迁移到项目文件中配置,能避免很多版本相关的构建顺序问题
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

