16

我正在编写一个游戏开发 IDE,它创建和编译 .NET 项目(我在过去几年一直在研究)并且正在更新它以生成不仅适用于 Windows/Visual Studio 的输出,还用于 Linux/MonoDevelop(.NET 的一个非常简单的过程,但仍需要一些调整)。

作为其中的一部分,我发现有必要开始生成一个 app.config 文件作为其中的一部分,以将依赖的 DLL 名称映射到具有 <dllmap> 元素的 Linux 依赖项名称。我对谁负责将 app.config 文件复制到输出名称 app.exe.config 感到困惑。在 Visual Studio 项目中,app.config 的构建操作似乎通常设置为“无”,其设置表明它不会被复制到任何地方,但是当 Visual Studio 编译项目时,它会生成 app.exe.config (虽然我有时发现这是不可靠的)。当我使用 MSBuild 构建由 IDE 生成的解决方案文件时(用于调试目的),MSBuild 将 app.config 复制到 app.exe.config。但是当我使用 CSharpCodeProvider.CompileAssemblyFromFile 编译项目时,它(自然)不会 t 喜欢将配置文件作为源代码包含在内(“app.config(1,1) : error CS0116: A namespace does not directly contain members such as fields or methods”),当然它不会将其复制到当我不将其作为输入时输出。将 app.config 独立复制到 app.exe.config 是我的责任,还是有更标准的方法?

获取第一个 *.config 文件是硬连线吗?在我的 IDE 中,可以想象 app.config 文件将被重命名或添加另一个文件(就像在 Visual Studio 中一样)。对我来说,IDE 对配置文件有这个秘密操作似乎很奇怪(我认为 MonoDevelop 在这方面的行为类似,因为我也找不到配置文件的特殊操作)。我什至不知道它如何选择此秘密操作适用的文件。

4

5 回答 5

8

C# 编译器根本不关心配置文件。构建环境(MSBuild 和 VS)将负责自己复制该文件。

于 2009-03-30T14:51:29.877 回答
8

命令:

  1. 项目目录中的第一个具有无构建操作的 app.config 文件
  2. 项目目录中的第一个带有内容构建操作的 app.config 文件
  3. 第一个具有无构建操作的 app.config 文件,位于子目录中
  4. 第一个带有内容构建操作的 app.config 文件,位于子目录中

msbuild/xbuild 还允许您通过设置 $(AppConfig) 属性来覆盖它。

于 2010-03-30T13:24:55.617 回答
5

一个稍微技术性的答案 - 您的项目Microsoft.CSharp.targets通过 csproj 文件中的这个键引用:

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

c:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets根据您的框架版本,此文件将解析为类似的内容。

在它里面你有这个部分可以完成工作:

  <!--
    ============================================================
                                        _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>

App.Config 文件似乎是作为环境变量传递的(它应该存在,但是谁设置的,​​我不知道):

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

编辑:有关如何选择 app.config,请参阅此答案 - https://stackoverflow.com/a/40293508/492336

app.config 的处理是特殊的,它是按名称处理的,构建过程会按照这个顺序选择 app.config 文件:

  • 选择在主项目中设置的值 $(AppConfig)。
  • 在与项目相同的文件夹中选择@(None) App.Config。
  • 选择与项目相同的文件夹中的@(Content) App.Config。
  • 在项目的任何子文件夹中选择@(None) App.Config。
  • 在项目的任何子文件夹中选择@(Content) App.Config。
于 2017-08-30T13:00:09.283 回答
1

我认为 MSBuild 负责复制。如果您会挖掘库存 .target 文件,那么您可能会找到相应的指令。VS 本身不会复制。

于 2009-03-30T15:09:24.047 回答
1

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

于 2009-03-31T09:09:12.640 回答