如何在运行时获取构建配置?

29

有人知道如何在C#代码中获取当前构建配置$(Configuration)吗?

7个回答

31

在.NET中有一个叫做AssemblyConfigurationAttribute的东西。你可以使用它来获得构建配置的名称。

var assemblyConfigurationAttribute = typeof(CLASS_NAME).Assembly.GetCustomAttribute<AssemblyConfigurationAttribute>();
var buildConfigurationName = assemblyConfigurationAttribute?.Configuration;

我已经编辑了我的被接受的答案并链接到了这里。很好的发现,Egor :) - Binary Worrier

22
如果您在项目中卸载(右键单击菜单),并将此内容添加到</Project>标记之前,它将保存一个包含您配置的文件。然后,您可以将其读回以在代码中使用。
<Target Name="BeforeBuild">
    <WriteLinesToFile File="$(OutputPath)\env.config" 
                      Lines="$(Configuration)" Overwrite="true">
    </WriteLinesToFile>
</Target>

我已经使用了Vaccano的解决方案。 我必须根据每个构建配置动态更改一些配置,而不仅仅是调试或发布,并且这个解决方案非常适合我。 谢谢。 - MsBugKiller
我将这个方法与Wix#(WixSharp)安装程序一起使用,以便将我的C#控制台应用程序“发布”构建二进制文件和配置文件提供给Wix#安装程序,并且它完全满足我的需求!(Wix#基于Windows Installer XML工具构建MSI安装程序,https://wixtoolset.org/,Wix#允许您编写安装程序的C#代码生成WiX xml文件,而不是“在XML中编码”。https://github.com/oleg-shilo/wixsharp/wiki/Building-MSI-%E2%80%93-Step-by-step-tutorial。另请参见https://www.infoq.com/articles/WixSharp/。) - Developer63
感谢@vaccano - 我正在使用这个来处理为集成测试加载正确的appsettings.environment.json。<Target Name="PreBuild" BeforeTargets="PreBuildEvent"> <WriteLinesToFile File="$(TargetDir)\env.config" Lines="$(ConfigurationName)" Overwrite="true"></WriteLinesToFile> </Target> - Jason Slocomb

19

更新

这个问题的答案在Egor在这个答案列表中提供的答案(这里)。

你不能真正地做到这一点。
你可以定义一些“条件编译符号”,如果你查看项目设置的“构建”页面,你可以在那里设置它们,这样你就可以编写#if语句来测试它们。

对于调试版本,默认情况下会自动注入DEBUG符号(这可以关闭)。

因此,您可以编写如下代码:

#if DEBUG
        RunMyDEBUGRoutine();
#else
        RunMyRELEASERoutine();
#endif

然而,除非你有充分的理由,否则不要这样做。一个在调试构建和发布构建之间具有不同行为的应用程序对任何人都没有好处。


1
在开发Windows服务时,这可能会有所帮助(无需安装/更容易调试) - Scoregraphic
@Scoregraphic:然而,它们的行为却非常不同(服务与命令行应用程序)!!! - Dirk Vollmar
为什么条件表达式找不到我的自定义配置?我有这样的代码:#if WCFDebug /我的代码/ #endif - 但它根本找不到。我已经在设置中添加了配置。 - FrenkyB
1
如果你有开发、测试、质量保证、预生产、生产等环境呢? - Marcus
1
@Marcus 然后在您的项目属性中为它们定义条件编译符号。 - Elkvis
@Marcus 上面的答案可能在几年前是正确的,但现代版本的.NET可以让您获得信息。请参见下面Egor Novikov的答案。 - David

10

可以使用条件编译符号来实现此目的。您可以在每个项目的属性>构建设置窗格中定义自定义符号,然后使用#if指令在代码中测试它们。

以下示例展示了如何定义符号UNOEURO以及如何在代码中使用它。

在此处定义UNOEURO符号

bool isUnoeuro = false;
#if UNOEURO
    isUnoeuro = true;
#endif

5
  1. 安装SlowCheetah Visual Studio扩展。
  2. 右键单击配置文件,选择“添加转换”。

添加转换

  1. 请注意每个生成配置的转换。

每个生成配置的转换

  1. 将“Build” appSetting放置到根配置文件中:
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <startup> 
          <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
        </startup>
      <appSettings>
        <add key="Build" value="" />
      </appSettings>
    </configuration>

在每个转换文件中放置一个“Build”指令。
    <?xml version="1.0" encoding="utf-8"?>
    <!--For more information on using transformations see the web.config examples at http://go.microsoft.com/fwlink/?LinkId=214134. -->
    <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
      <appSettings>
        <add key="Build" value="Debug" xdt:Transform="Replace" xdt:Locator="Match(key)"/>
      </appSettings>
    </configuration>
  1. 在 C# 代码中获取 "Build" appSetting 的值:

ConfigurationManager.AppSettings["Build"]



1
对于 .Net Standard 和 Core,您可以使用 .Assembly.GetCustomAttribute<AssemblyConfigurationAttribute>() 方法。 对于 .NET Framework,Assembly 解决方案不适用,而 Jim G. 提供的解决方案是我认为最好的方法来完成工作。您不需要使用 Visual Studio 扩展,但需要稍微修改 csproj 文件以使其正常工作。您可以在此处详细了解如何使其正常工作:https://stackoverflow.com/a/5109530/8025440 - undefined

1
你可以使用带有条件属性的常规静态方法来设置标志以检测DEBUG或RELEASE模式。SetDebugMode方法仅在DEBUG模式下运行时调用,否则运行时会忽略它。
public static class AppCompilationConfiguration
{
    private static bool debugMode;

    private static bool IsDebugMode()
    {
        SetDebugMode();
        return debugMode;
    }

    //This method will be loaded only in the case of DEBUG mode. 
    //In RELEASE mode, all the calls to this method will be ignored by runtime.
    [Conditional("DEBUG")]
    private static void SetDebugMode()
    {
        debugMode = true;
    }

    public static string CompilationMode => IsDebugMode() ? "DEBUG" : "RELEASE";

}

您可以在代码中像下面这样调用它:
 Console.WriteLine(AppCompilationConfiguration.CompilationMode);

0

我不相信你可以在编译时将其注入到程序集中,但你可以使用MSBuild并将其添加到应用程序的配置文件中来实现它。

请参阅这篇关于如何使用MSBuild进行多环境配置文件的博客文章 - http://adeneys.wordpress.com/2009/04/17/multi-environment-config/

或者,您可以编写一个MSBuild任务,该任务将编辑某个已编译文件(您的C#或VB文件),并在BeforeBuild任务中运行它。这可能会非常棘手,因为您需要确定将其注入到文件的哪个位置,但只要您设置了某种标记化,就应该能够做到。我也怀疑它是否会很漂亮!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接