简体   繁体   English

谁将app.config复制到app.exe.config?

[英]Who copies app.config to app.exe.config?

I'm writing a game development IDE that creates and compiles .NET projects (which I've been working on for the past few years) and am in the process of updating it to generate output not only for Windows/Visual Studio, but also for Linux/MonoDevelop (a thrillingly simple process for .NET, but still requiring some tweaks). 我正在编写一个游戏开发IDE,用于创建和编译.NET项目(我过去几年一直在研究),并且我正在更新它以生成输出,不仅适用于Windows / Visual Studio,还适用于对于Linux / MonoDevelop(一个非常简单的.NET进程,但仍然需要一些调整)。

As part of this, I have found it necessary to start generating an app.config file as part of this to map dependent DLL names to Linux dependency names with <dllmap> elements. 作为其中的一部分,我发现有必要开始生成app.config文件作为其中的一部分,以将依赖的DLL名称映射到具有<dllmap>元素的Linux依赖项名称。 I'm confused about who's responsible for copying the app.config file to the output name app.exe.config. 我很担心谁负责将app.config文件复制到输出名称app.exe.config。 In a Visual Studio project, the Build Action for app.config seems to normally be set to "None" and its settings indicate that it won't be copied anywhere, yet when Visual Studio compiles the project it generates app.exe.config (though I've sometimes found this to be unreliable). 在Visual Studio项目中,app.config的Build Action通常设置为“None”,其设置表明它不会被复制到任何地方,但是当Visual Studio编译项目时它会生成app.exe.config(虽然我有时发现这是不可靠的)。 When I use MSBuild to build a solution file generated by the IDE (for debugging purposes), MSBuild copies app.config to app.exe.config. 当我使用MSBuild构建IDE生成的解决方案文件(用于调试目的)时,MSBuild将app.config复制到app.exe.config。 But when I compile the project with CSharpCodeProvider.CompileAssemblyFromFile it (naturally) doesn't like the config file being included as source code ("app.config(1,1) : error CS0116: A namespace does not directly contain members such as fields or methods"), and of course it doesn't copy it to the output when I don't include it as an input. 但是当我使用CSharpCodeProvider.CompileAssemblyFromFile编译项目时(它自然)不喜欢将配置文件作为源代码包含(“app.config(1,1):错误CS0116:命名空间不直接包含诸如字段之类的成员或方法“),当然,当我不将它作为输入包括它时,它不会将它复制到输出。 Is it my responsibility to simply copy app.config to app.exe.config independently, or is there a more standard way of doing this? 我是否有责任单独将app.config复制到app.exe.config,或者有更标准的方法吗?

Is it hardwired to take the first *.config file? 是否硬连线采用第一个* .config文件? In my IDE it's conceivable that the app.config file would be renamed or another one added (just as in Visual Studio). 在我的IDE中,可以想象app.config文件将被重命名或添加另一个(就像在Visual Studio中一样)。 It seems odd to me that the IDE has this secret action for config files (I think MonoDevelop behaves similarly in this regard because I couldn't find a special action for config files there either). 我觉得IDE对配置文件有这个秘密行为似乎很奇怪(我认为MonoDevelop在这方面表现相似,因为我找不到配置文件的特殊操作)。 I don't know how it even picks to what files this secret action applies. 我不知道它甚至会选择这个秘密行动适用的文件。

The C# compiler does not care about the config file at all. C#编译器根本不关心配置文件。 Build environments (MSBuild and VS) will take care of copying that file themselves. 构建环境(MSBuild和VS)将负责自己复制该文件。

Order: 订购:

  1. first app.config file with None build action, in the project directory 项目目录中的第一个带有无构建操作的app.config文件
  2. first app.config file with Content build action, in the project directory 项目目录中包含Content build action的第一个app.config文件
  3. first app.config file with None build action, in a subdirectory 第一个带有无构建操作的app.config文件,位于子目录中
  4. first app.config file with Content build action, in a subdirectory 第一个带有内容构建操作的app.config文件,位于子目录中

msbuild/xbuild also allow you to override this by setting the $(AppConfig) property. msbuild / xbuild还允许您通过设置$(AppConfig)属性来覆盖它。

A slightly more technical answer - your project references Microsoft.CSharp.targets via this key in the csproj file: 稍微更具技术性的答案 - 您的项目通过csproj文件中的此键引用Microsoft.CSharp.targets

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

This file would resolve to something like c:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\Microsoft.Common.targets , depending on your framework version. 此文件将解析为c:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\Microsoft.Common.targets ,具体取决于您的框架版本。

Inside of it you have this section which does the work: 在它的内部你有这个部分做的工作:

  <!--
    ============================================================
                                        _CopyAppConfigFile

    Copy the application config file.
    ============================================================
    -->
  <Target
      Name="_CopyAppConfigFile"
      Condition=" '@(AppConfigWithTargetPath)' != '' "
      Inputs="@(AppConfigWithTargetPath)"
      Outputs="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')">

    <!--
        Copy the application's .config file, if any.
        Not using SkipUnchangedFiles="true" because the application may want to change
        the app.config and not have an incremental build replace it.
        -->
    <Copy
        SourceFiles="@(AppConfigWithTargetPath)"
        DestinationFiles="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')"
        OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
        Retries="$(CopyRetryCount)"
        RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
        UseHardlinksIfPossible="$(CreateHardLinksForAdditionalFilesIfPossible)"
            >

      <Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>

    </Copy>

  </Target>

The App.Config file seems to be passed as an environment variable (it is expected to be present but who sets it, I don't know): App.Config文件似乎作为一个环境变量传递(它应该存在,但谁设置它,我不知道):

<ItemGroup>
  <AppConfigWithTargetPath Include="$(AppConfig)" Condition="'$(AppConfig)'!=''">
    <TargetPath>$(TargetFileName).config</TargetPath>
  </AppConfigWithTargetPath>
</ItemGroup>

Edit: For how app.config is selected, see this answer - https://stackoverflow.com/a/40293508/492336 . 编辑:有关如何选择app.config,请参阅此答案 - https://stackoverflow.com/a/40293508/492336

The handling of app.config is special, it is treated By Name, the build process will select the app.config file following this order: app.config的处理很特殊,按名称处理,构建过程将按照以下顺序选择app.config文件:

  • Choose the value $(AppConfig) set in the main project. 选择主项目中设置的值$(AppConfig)。
  • Choose @(None) App.Config in the same folder as the project. 在与项目相同的文件夹中选择@(无)App.Config。
  • Choose @(Content) App.Config in the same folder as the project. 在与项目相同的文件夹中选择@(Content)App.Config。
  • Choose @(None) App.Config in any subfolder in the project. 在项目的任何子文件夹中选择@(无)App.Config。
  • Choose @(Content) App.Config in any subfolder in the project. 在项目的任何子文件夹中选择@(Content)App.Config。

I think MSBuild is responsible for copying. 我认为MSBuild负责复制。 If you would dig trough stock .target files, then you'd probably find corresponding directives. 如果您要挖掘库存.target文件,那么您可能会找到相应的指令。 VS by itself doesn't copy. VS本身不会复制。

另请注意,Visual Studio确实验证了配置文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM