在 MSBuild 中指定程序集版本号作为命令行参数

问题描述 投票:0回答:5

我希望能够指定在构建期间生成的所有程序集的版本号作为 MSBuild 命令参数,如下所示:

MSBuild.exe /p:version=5.4.3.0 

我已经查看了

AssemblyInfoTask
,但在我看来,在这种情况下这不是一个好的解决方案。

msbuild versioning
5个回答
51
投票

对于使用

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


22
投票

我知道这是一个老问题,但谷歌将我带到这里作为最佳结果。

我在更新的链接中遵循了一个简单的解决方案(感谢彼得更新的链接)。无需扩展包。

基本上,您需要做的是添加“BuildCommon.targets”文件并相应地修改您的 csproj 文件以在 msbuild 中指定版本号,例如:

msbuild.exe abc.sln /p:Configuration=Release;VersionAssembly=1.2.3.4

希望这有帮助。


20
投票

我一直使用 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 文件在构建开始之前全部得到处理。这不是你想要的吗?


8
投票

最上面的答案很好,但我需要做一些调整。我们有一个包含 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)
    的值。

2
投票

最佳答案确实很好。此外,这里有一些可能被证明有用的澄清/建议(也许从上面的帖子中显而易见),以避免任何自定义目标、BeforeBuild 等。

  • 对于 SDK 项目(即没有 AssemblyInfo.cs):
    /p:Version='1.0.0-patch'
    也适用于 msbuild.exe(当然还有 dotnet.exe),而无需 any csproj 更改。例如,当针对 still 不支持 dotnet.exe 的 v3 Wix 安装项目时很有用。另外,您可以将 $AssemblyVersion 和 $FileVersion 分配给空值,因为 $Version 会自动分配它们。
  • 对于非 SDK 项目,与其使用自定义目标、BeforeBuild 等修改 csproj,不如将它们升级到 SDK 样式项目,即删除过时的 AssemblyInfo.cs 用法,这可能会更简单/更快。请参阅迁移项目
© www.soinside.com 2019 - 2024. All rights reserved.