首页 > 解决方案 > 在编译期间使用 MSBuild.exe 设置布尔变量

问题描述

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

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

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

标签: c#wpfmsbuild

解决方案


你有2个选择。

第一种是使用此 MSBuild 属性来控制是否定义了特定的预处理器符号,然后#if在您的 C# 代码中使用:

<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"

推荐阅读