对您的问题的简短回答是不,您不能以这种方式使用预处理器指令。另一个答案中说明了一种解决方法,涉及定义一个常数。这可能是旧式项目的唯一解决方案。
但是,如果您使用 SDK 样式的项目格式,AssemblyInfo
则可以在项目文件中设置属性。以下属性对应于上面定义的属性:
InformationalVersion
->AssemblyInformationalAttribute
AssemblyVersion
->AssemblyVersion
FileVersion
->AssemblyFileVersion
Version
-> 如果省略,则可以映射到上述任何/所有内容
只要is ,所有其他程序集属性都可以通过属性设置。这要求您删除文件以防止重复这些属性。*GenerateAssemblyInfo
true
AssemblyInfo.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 文件,则必须通过利用各个GenerateX
MSBuild 属性来禁用它们的自动生成。
** 有关其中一些属性的详细说明,请参阅此博客文章。