Кто копирует app.config в app.exe.config? - PullRequest
14 голосов
/ 30 марта 2009

Я пишу IDE для разработки игр, которая создает и компилирует проекты .NET (над которыми я работаю последние несколько лет), и в настоящее время обновляю ее, чтобы генерировать выходные данные не только для Windows / Visual Studio , но также и для Linux / MonoDevelop (захватывающий и простой процесс для .NET, но все же требующий некоторых настроек).

Как часть этого, я счел необходимым начать генерирование файла app.config как части этого, чтобы отобразить зависимые имена DLL в имена зависимостей Linux с элементами . Я не понимаю, кто отвечает за копирование файла app.config в выходное имя app.exe.config. В проекте Visual Studio действие Build для app.config обычно имеет значение «Нет», и его настройки указывают, что он никуда не будет скопирован, но когда Visual Studio компилирует проект, он генерирует app.exe.config ( хотя я иногда нахожу это ненадежным). Когда я использую MSBuild для создания файла решения, сгенерированного IDE (для целей отладки), MSBuild копирует app.config в app.exe.config. Но когда я компилирую проект с помощью CSharpCodeProvider.CompileAssemblyFromFile, ему (естественно) не нравится, когда файл конфигурации включается в качестве исходного кода ("app.config (1,1): ошибка CS0116: пространство имен напрямую не содержит членов, таких как поля или методы "), и, конечно, он не копирует его в вывод, если я не включаю его в качестве ввода. Это моя обязанность - просто скопировать app.config в app.exe.config независимо или есть более стандартный способ сделать это?

Трудно ли взять первый файл * .config? В моей IDE вполне возможно, что файл app.config будет переименован или добавлен другой (как в Visual Studio). Мне кажется странным, что в среде IDE есть это секретное действие для файлов конфигурации (я думаю, что MonoDevelop ведет себя аналогично в этом отношении, потому что я также не смог найти специальное действие для файлов конфигурации). Я не знаю, как он выбирает, к каким файлам применяется это секретное действие.

Ответы [ 5 ]

8 голосов
/ 30 марта 2009

Компилятору C # вообще нет дела до файла конфигурации. Среды сборки (MSBuild и VS) сами позаботятся о копировании этого файла.

7 голосов
/ 30 марта 2010

Заказать:

  1. первый файл app.config с действием «Нет» в каталоге проекта
  2. первый файл app.config с действием Content build, в каталоге проекта
  3. первый файл app.config с действием «Нет» в подкаталоге
  4. первый файл app.config с действием построения содержимого в подкаталоге

msbuild / xbuild также позволяет вам переопределить это, установив свойство $ (AppConfig).

1 голос
/ 30 августа 2017

Немного более технический ответ - ваш проект ссылается на 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), установленное в основном проекте.
  • Выберите @ (Нет) App.Config в той же папке, что и проект.
  • Выберите @ (Content) App.Config в той же папке, что и проект.
  • Выберите @ (Нет) App.Config в любой подпапке в проекте.
  • Выберите @ (Content) App.Config в любой подпапке в проекте.
1 голос
/ 31 марта 2009

Обратите внимание, что Visual Studio проверяет файл конфигурации.

1 голос
/ 30 марта 2009

Я думаю, что MSBuild отвечает за копирование. Если бы вы копали стандартные файлы .target, то вы, вероятно, нашли бы соответствующие директивы. VS само по себе не копирует.

...