1

在 C# 项目中,我们手动增加版本,并有一个顶级文件MyAssemblyInfo.cs包含

[assembly: AssemblyVersion("31.1.13")]
[assembly: AssemblyFileVersion("31.1.13")]
[assembly: AssemblyInformationalVersion("31.1.13-V1.0.0")]

我想避免重复版本。例如,使用 C 预处理器,可以将其写为

#define VERSION "31.1.13"
[assembly: AssemblyVersion(VERSION)]
[assembly: AssemblyFileVersion(VERSION)]
[assembly: AssemblyInformationalVersion(VERSION "-V1.0.0")]

有没有办法在不使用任何外部工具的情况下在 C# 中实现这一点?

4

2 回答 2

3
[assembly: AssemblyFileVersion(AppVersion.Version)]
[assembly: AssemblyInformationalVersion(AppVersion.Version)]
// you can use + here but the format you use shows as invalid version for me
[assembly: AssemblyVersion(AppVersion.Version)] 

// this must be at the end of the global declarations
internal class AppVersion
{
    public const string Version = "31.1.13";
}
于 2020-06-26T09:35:07.707 回答
1

对您的问题的简短回答是,您不能以这种方式使用预处理器指令。另一个答案中说明了一种解决方法,涉及定义一个常数。这可能是旧式项目的唯一解决方案。

但是,如果您使用 SDK 样式的项目格式,AssemblyInfo则可以在项目文件中设置属性。以下属性对应于上面定义的属性:

  • InformationalVersion->AssemblyInformationalAttribute
  • AssemblyVersion->AssemblyVersion
  • FileVersion->AssemblyFileVersion
  • Version-> 如果省略,则可以映射到上述任何/所有内容
    • 设置文件/程序集版本时具有删除后缀模式的特殊逻辑

只要is ,所有其他程序集属性都可以通过属性设置。这要求您删除文件以防止重复这些属性。*GenerateAssemblyInfotrueAssemblyInfo.cs

我通常解决这个问题的方法是在我的项目文件中定义我自己的一组与版本相关的属性(请参阅下面的注释了解原因)。例如,您可能有以下内容:

<PropertyGroup>
   <GenerateAssemblyInfo>true</GenerateAssemblyInfo>
   <BaseVersion>31.1.13</BaseVersion>
   <InfoSuffix>v1.0.0</InfoSuffix>
</PropertyGroup>
<PropertyGroup>
   <!-- note: "-v1" is invalid in an Assembly Version; I assumed you meant this on the Informational one -->
   <InformationalVersion>$(BaseVersion)-$(InfoSuffix)</InformationalVersion>
   <AssemblyVersion>$(BaseVersion)</AssemblyVersion>
   <FileVersion>$(BaseVersion)</FileVersion>
</PropertyGroup>

如果您想显式覆盖它们,您可以在命令行上将这些属性中的任何一个传递给 MSBuild 或 dotnet build:

dotnet build -p:InfoSuffix=v2.0+1234
# alternatively, specify the MSBuild properties directly
dotnet build -p:FileVersion=1.2.3.4 -p:InformationalVersion=5.6.7.8

如果您有多个项目,您可以在一个Directory.Build.props文件中设置所有这些属性,以便它们一次应用于您的所有项目。

一些笔记

首先,如果您正在使用该Directory.Build.props机制并运行任何类型的后处理任务或类似 SourceLink(将信息附加到信息版本),您将需要将第二个属性组移动到Directory.Build.targets文件中。如果您想将属性显式传递给其他工具,例如dotnet pack.

其次,MSBuild 还有一系列其他版本相关的属性**。这些包括(但不限于):

  • SourceRevisionId- 附加到信息版本(我们的InfoSuffix
  • VersionPrefix- 基本版本
  • VersionSuffix- 设置预发行标签
  • PackageVersion- 生成 nuget 版本

您可以将它们与上面指定的组合使用。如果您想覆盖 project/props/targets 文件中的值,您甚至可以在命令行上将它们作为属性传递。

现在您可能想知道为什么我要费心定义自己的属性而不是使用内置属性。原因是 MSBuild 有一些奇怪的,有时甚至是意外的行为,具体取决于这些属性的组合是如何设置的。有趣的是,我注意到不同的行为取决于我设置的值以及我是在 VS、命令行还是使用 dotnet pack 构建。正因为如此,我更喜欢定义自己的属性,然后使用它们显式设置其他属性。它还允许我使用条件 MSBuild 逻辑来更轻松地设置版本的某些部分。虽然我承认,你的里程可能会有所不同。

* 如果您想为其他属性保留 AssemblyInfo.cs 文件,则必须通过利用各个GenerateXMSBuild 属性来禁用它们的自动生成。

** 有关其中一些属性的详细说明,请参阅此博客文章

于 2020-06-26T11:08:59.480 回答