我希望能够指定在构建期间生成的所有程序集的版本号作为 MSBuild 命令参数,如下所示:
MSBuild.exe /p:version=5.4.3.0
我已经查看了
AssemblyInfoTask
,但在我看来,在这种情况下这不是一个好的解决方案。
对于使用
dotnet.exe
构建的 SDK 样式项目,程序集版本属性是自动生成,因此您可以直接使用 /p:Version=5.4.3.0
。
如果您使用旧的项目格式,则需要将以下
BeforeBuild
步骤添加到您的 .csproj
文件中。 无需使用额外的.targets
和扩展包,因为MSBuild已经有一个很好的内置任务,它可以完成大部分工作:
<Target Name="BeforeBuild">
<ItemGroup>
<AssemblyAttributes Include="AssemblyVersion">
<_Parameter1>$(Version)</_Parameter1>
</AssemblyAttributes>
</ItemGroup>
<MakeDir Directories="$(IntermediateOutputPath)" />
<WriteCodeFragment Language="C#"
OutputFile="$(IntermediateOutputPath)Version.cs"
AssemblyAttributes="@(AssemblyAttributes)" />
<ItemGroup>
<Compile Include="$(IntermediateOutputPath)Version.cs" />
</ItemGroup>
</Target>
只需确保删除现有的
AssemblyVersion
属性,因为它现在将在构建过程中生成。
2020 年 7 月 29 日更新: Michael Parker 指出,如果您使用此方法并从 Visual Studio 进行构建,最终会在
Version.cs
文件中得到一个空版本。为了克服这个问题,我建议在您的 .csproj
或 Directory.Build.props
文件中定义默认版本值,如下所示:
<PropertyGroup>
...
<Version Condition="'$(Version)' == ''">1.0.0.0</Version>
</PropertyGroup>
如果未在命令行中指定版本,这会将其设置为
1.0.0.0
。
我知道这是一个老问题,但谷歌将我带到这里作为最佳结果。
我在更新的链接中遵循了一个简单的解决方案(感谢彼得更新的链接)。无需扩展包。
基本上,您需要做的是添加“BuildCommon.targets”文件并相应地修改您的 csproj 文件以在 msbuild 中指定版本号,例如:
msbuild.exe abc.sln /p:Configuration=Release;VersionAssembly=1.2.3.4
希望这有帮助。
我一直使用 MSBuild Community Tasks(最新版本 2017)中的 AssemblyInfo 任务,正如您在评论中一直描述的那样。
<!-- update standard assembly attribute in all projects -->
<Target Name="BeforeBuild" >
<Message Text="Updating AssemblyInfo to Version $(VersionNumber)"></Message>
<Message Text="Writing to AssemblyInfo files in $(SolutionRoot)"></Message>
<AssemblyInfo AssemblyInfoFiles="@(AssemblyInfoFiles)"
AssemblyCopyright="$(AssemblyCopyright)"
AssemblyVersion="$(VersionNumber)"
AssemblyFileVersion="$(VersionNumber)"
>
</AssemblyInfo>
</Target>
VersionNumber 值是从 MSBuild 项目文件外部传递的,与您所描述的完全一样:
MSBuild <project_file> /p:VersionNumber=<value>;...
我们使用 BeforeBuild 目标来确保 AssemblyInfo.cs 文件在构建开始之前全部得到处理。这不是你想要的吗?
最上面的答案很好,但我需要做一些调整。我们有一个包含 SDK 和非 SDK 项目混合的解决方案。此外,我们还使用
AspNetCompileMerge
来预编译 ASP.NET MVC 5 视图。使用属性名称 AssemblyAttributes
会导致 GenerateAssemblyInfo
中的 AspNetCompileMerge.targets
的目标被执行并失败。所以我最终通过Directory.Build.props
达到了整个解决方案共享的以下目标:
<PropertyGroup>
<Version Condition="'$(Version)' == ''">1.0.0.0</Version>
<AssemblyVersion Condition="'$(AssemblyVersion)' == ''">$(Version.Split('-')[0])</AssemblyVersion>
<FileVersion Condition="'$(FileVersion)' == ''">$(Version.Split('-')[0])</FileVersion>
<InformationalVersion Condition="'$(InformationalVersion)' == ''">$(Version)</InformationalVersion>
</PropertyGroup>
<Target Name="NonSdkGenerateAssemblyInfo" DependsOnTargets="PrepareForBuild" BeforeTargets="BeforeBuild" Condition="('$(UsingMicrosoftNETSdk)' != 'True' And '$(GenerateAssemblyInfo)' != 'False')">
<ItemGroup>
<NonSdkAssemblyAttributes Include="AssemblyVersion">
<_Parameter1>$(AssemblyVersion)</_Parameter1>
</NonSdkAssemblyAttributes>
<NonSdkAssemblyAttributes Include="AssemblyFileVersion">
<_Parameter1>$(FileVersion)</_Parameter1>
</NonSdkAssemblyAttributes>
<NonSdkAssemblyAttributes Include="AssemblyInformationalVersion">
<_Parameter1>$(InformationalVersion)</_Parameter1>
</NonSdkAssemblyAttributes>
</ItemGroup>
<WriteCodeFragment AssemblyAttributes="@(NonSdkAssemblyAttributes)"
Language="C#"
OutputDirectory="$(IntermediateOutputPath)"
OutputFile="AssemblyInfo.cs">
<Output TaskParameter="OutputFile" ItemName="Compile" />
<Output TaskParameter="OutputFile" ItemName="FileWrites" />
</WriteCodeFragment>
</Target>
如果需要,您可以添加其他属性。默认版本号是
1.0.0.0
,您可以在命令行上指定其他版本号,模仿 SDK 行为:
AssemblyVersion
和 FileVersion
默认为不带后缀的 $(Version)
的值。例如,如果 $(Version)
是 1.2.3-beta.4
,则该值将为 1.2.3
。InformationalVersion
默认为 $(Version)
的值。最佳答案确实很好。此外,这里有一些可能被证明有用的澄清/建议(也许从上面的帖子中显而易见),以避免任何自定义目标、BeforeBuild 等。
/p:Version='1.0.0-patch'
也适用于 msbuild.exe(当然还有 dotnet.exe),而无需 any csproj 更改。例如,当针对 still 不支持 dotnet.exe 的 v3 Wix 安装项目时很有用。另外,您可以将 $AssemblyVersion 和 $FileVersion 分配给空值,因为 $Version 会自动分配它们。