2009-03-30 5 views
14

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

В качестве части этого я нашел необходимым начать создание файла app.config как часть этого, чтобы сопоставить имена зависимых DLL с именами зависимостей Linux с <dllmap>. Я смущен тем, кто ответственен за копирование файла app.config в выходное имя app.exe.config. В проекте Visual Studio для Action для 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 ведет себя аналогично в этом отношении, потому что я не мог найти специальное действие для файлов конфигурации там). Я не знаю, как он даже выбирает, в каких файлах применяется это секретное действие.

+0

Чтобы уточнить, мой вопрос, так как я использую CSharpCodeProvider для компиляции кода (не прибегая к команде оболочки, такие как MSBuild для компиляции проекта), что правильный способ получить app.exe .config на выходе? – BlueMonkMN

+0

Я бы предложил использовать MSBuild в вашей среде IDE и создать задачи MSBuild для любого созданного вами специального выпуска, который MSVuild не поддерживает. Это позволит MSBuild скомпилировать ваши решения. Кроме того, это упростит интеграцию вашего продукта с постоянной интеграцией, такой как TeamCity. – grover

+0

MSBuild уже может скомпилировать мои решения. И когда он это делает, он уже правильно обрабатывает app.config. CSharpCodeProvider кажется более прямым решением с меньшими накладными расходами, чем обход MSBuild. IDE создает файл решения, но не использует его при компиляции внутри. – BlueMonkMN

ответ

8

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

+0

Моя IDE не использует MSBuild для компиляции проекта. Он использует CSharpCodeProvider. Итак, что должна делать моя IDE? – BlueMonkMN

+0

После компиляции он должен скопировать файл конфигурации с помощью 'File.Copy'. –

+0

Скопируйте первый файл * .config в outputname.exe.config и проигнорируйте любой другой файл * .config (который не должен существовать)? – BlueMonkMN

1

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

1

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

7

Заказ:

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

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

+0

Ваше упоминание о свойстве '$ (AppConfig)' было действительно полезно для меня. Я чувствую, что вы могли бы улучшить этот ответ, указав еще немного информации о том, где вы нашли эту информацию. Я нашел несколько дополнительных объяснений [здесь] (https://timvw.be/2008/03/17/easily-switching-between-appconfig-files-with-msbuild/), но если есть официальная ссылка, которая будет еще лучше , Если нет, просто упоминание файла 'целей' также будет приветствоваться. – julealgon

0

Немного более технический ответ - ваш проект ссылается 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> 

Edit: Для того, как выбрано app.config см этого ответа - https://stackoverflow.com/a/40293508/492336.

Обработка app.config является особенным, он обрабатывается по имени, процесс сборки будет выбрать файл app.config следуя порядку:

  • Выберите значение $ (AppConfig), установленного в основного проекта.
  • Выберите @ (Нет) App.Config в той же папке, что и проект.
  • Выберите @ (Content) App.Config в той же папке, что и проект.
  • Выберите @ (Нет) App.Config в любой подпапке в проекте.
  • Выберите @ (Content) App.Config в любой подпапке в проекте.