在编译期间使用 MSBuild.exe 设置布尔变量

Set Boolean variable during the compile time using MSBuild.exe

在我们的 C# 代码中,我们有一个带有布尔变量 IS_FEATURE_X_ENABLED 的静态 class,我们希望能够在编译期间设置这个变量,这意味着当我们调用 MSBuild.exe 该值将作为参数包含在内。例如:

MSBuild.exe FeatureFlexibleApp.sln -p:IsFeatureXEnabled=true

这样做的原因是我们希望能够构建具有特定配置的二进制文件,但在编译之前这个值是未知的。如果客户想要此功能,他们可以 select 在我们的网页上构建二进制文件并将其打包在 Jenkins 服务器上,然后 link 将向用户发送下载(通过电子邮件发送)或者如果他们等待编译完成,它将显示在网页上)。在这种情况下只使用一个变量,但实际上这个数字不必有限制(因此预先构建所有可能的组合不是一个可行的选择)。

您有 2 个选择。

首先是使用这个 MSBuild 属性 来控制是否定义了特定的预处理器符号,然后在你的 C# 代码中使用 #if:

<PropertyGroup>
  <DefineConstants Condition="'$(IsFeatureXEnabled)' == 'true'">$(DefineConstants);IS_FEATURE_X_ENABLED</DefineConstants>
</PropertyGroup>

然后:

#if IS_FEATURE_X_ENABLED
    // Code compiled only if feature X is enabled
#endif

但是,如果您沿着这条路走下去,则更容易废弃 csproj 中的样板文件,直接从命令行设置 DefineConstants:

MSBuild.exe FeatureFlexibleApp.sln -p:DefineConstants=IS_FEATURE_X_ENABLED

另一种是利用MSBuild属性的值写一个程序集级别的属性,然后在运行时用代码读取这个属性。

在程序集的不同构建之间唯一会发生变化的是这些程序集级属性的值:其他一切都是在运行时确定的,这可能是也可能不是您想要的。但是,这确实意味着您可以将任何旧字符串传递到您的代码中,而不仅仅是二进制启用/未启用。

<ItemGroup>
  <AssemblyAttribute Include="Namespace.Of.Your.ConfigurationAttribute">
    <IsFeatureXEnabled>$(IsFeatureXEnabled)</IsFeatureXEnabled>
  </AssemblyAttribute>
</ItemGroup>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
internal class ConfigurationAttribute : Attribute
{
    public string IsFeatureXEnabled { get; set; }
}

...

bool isFeatureXEnabled = typeof(...).Assembly
    .GetCustomAttribute<ConfigurationAttribute>().IsFeatureXEnabled == "true"