我希望能够像这样使用MSBuild命令行参数指定在构建期间生成的所有程序集的版本号:
MSBuild.exe /p:version=5.4.3.0
我查看了AssemblyInfoTask
,但在这种情况下,它似乎不是一个好的解决方案。
我希望能够像这样使用MSBuild命令行参数指定在构建期间生成的所有程序集的版本号:
MSBuild.exe /p:version=5.4.3.0
我查看了AssemblyInfoTask
,但在这种情况下,它似乎不是一个好的解决方案。
对于使用dotnet.exe
构建的SDK-style项目,程序集版本属性将自动生成,因此您可以直接使用/p:Version=5.4.3.0
。
如果使用旧的项目格式,则需要在.csproj
文件中添加以下BeforeBuild
步骤。不需要使用额外的.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
。
<Target Name="BeforeBuild">
应该在 <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
行 之后指定,因为我刚学到这个。 - oleksa[assembly: AssemblyVersion
和 [assembly: AssemblyFileVersion
。 - daniol我知道这是一个老问题,但谷歌把我带到了这里作为最佳结果。
我在更新的链接中遵循了一个简单的解决方案(感谢Peter提供的更新链接)。不需要扩展包。
基本上你需要做的就是添加一个“BuildCommon.targets”文件,并相应地修改你的csproj文件,以便在msbuild中指定版本号,例如:
msbuild.exe abc.sln /p:Configuration=Release;VersionAssembly=1.2.3.4
/p:Version=1.2.4
。 - CubanX我经常像您在评论中描述的那样使用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文件都得到处理。这不是你想要的吗?
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),无需 任何 csproj 更改。例如,在针对仍然不支持 dotnet.exe 的 v3 Wix 安装程序项目时非常有用。此外,您可以将 $AssemblyVersion 和 $FileVersion 分配为空值,因为 $Version 将自动分配它们。