这是由于MSBuild's Property Evaluation Order。
在csproj 文件中设置AssemblyVersion在设置AssemblyName 之前可以正常工作:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<AssemblyVersion>1.0.0.0</AssemblyVersion>
<AssemblyName>$(MSBuildProjectName)$(AssemblyVersion)</AssemblyName>
</PropertyGroup>
</Project>
1>CSharpScratchpad -> C:\Projects\CSharpScratchpad\bin\Debug\net6.0\CSharpScratchpad1.0.0.0.dll
在 cmets 中,您还声明要使用通配符 AssemblyVersion,例如 1.0.*。我不知道访问 MSBuild 内部生成的扩展的最终形式的好方法,所以我只能提供一个稍微难看的构建后副本,从构建的程序集中检索版本:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<AssemblyVersion>1.0.*</AssemblyVersion>
<Deterministic>false</Deterministic>
</PropertyGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
<Output TaskParameter="Assemblies" ItemName="AssemblyIdentity"/>
</GetAssemblyIdentity>
<Exec Command='COPY "$(TargetPath)" "$(TargetDir)$(TargetName)%(AssemblyIdentity.Version)$(TargetExt)" /Y' />
</Target>
</Project>
在后续评论中,您只想将 major.minor 版本附加到文件名中。您可以通过创建程序集版本的System.Version 实例,然后调用它的ToString(int fieldCount) 方法,以便它只返回前两个段来做到这一点。为了便于阅读,我已将结果存储在 MajorMinor 属性中,但如果您愿意,可以将其全部合并到一行中。这将是新的后期构建目标:
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
<Output TaskParameter="Assemblies" ItemName="AssemblyIdentity"/>
</GetAssemblyIdentity>
<PropertyGroup>
<MajorMinor>$([System.Version]::new("%(AssemblyIdentity.Version)").ToString(2))</MajorMinor>
</PropertyGroup>
<Exec Command='COPY "$(TargetPath)" "$(TargetDir)$(TargetName)$(MajorMinor)$(TargetExt)" /Y' />
</Target>
我建议能够在几个月内向你的同事或你自己解释这一点。也许其他人知道对此有一个不那么复杂的解决方案。