Преобразование App.Config для проектов, которые не являются веб-проектами в Visual Studio?

Для веб-приложения Visual Studio 2010 у нас есть функции преобразования конфигурации, с помощью которых мы можем поддерживать несколько файлов конфигурации для разных сред. Но та же функция недоступна для файлов App.Config для служб Windows / WinForms или консольного приложения.

Существует обходной путь, предложенный здесь: Применение магии XDT к App.Config.

Однако это непросто и требует нескольких шагов. Есть ли более простой способ добиться того же для файлов app.config?


person Amitabh    schedule 09.06.2010    source источник
comment
Я наткнулся на следующую статью, которая выглядит немного проще, но сам не пробовал. fknut.blogspot.com/2009/11/ Кроме того, в MS Connect есть запрос функции, за который, возможно, стоит проголосовать, чтобы он был включен повсеместно в следующий SP или версию. connect.microsoft.com/VisualStudio/feedback/details/564414   -  person Kim R    schedule 14.06.2010


Ответы (14)


Теперь это работает с надстройкой Visual Studio, рассмотренной в этой статье: SlowCheetah - общее преобразование с помощью синтаксиса Web.configized. любой файл конфигурации XML.

Вы можете щелкнуть правой кнопкой мыши свой web.config и выбрать «Добавить преобразования конфигурации». Когда вы это сделаете, вы получите файлы web.debug.config и web.release.config. Вы можете создать web.whatever.config, если хотите, если имя совпадает с профилем конфигурации. Эти файлы - это просто изменения, которые вы хотите внести, а не полная копия вашего web.config.

Вы можете подумать, что захотите использовать XSLT для преобразования файла web.config, но, хотя они интуитивно кажутся правильными, на самом деле они очень подробны.

Вот два преобразования, одно с использованием XSLT, а другое с использованием синтаксиса / пространства имен преобразования XML-документа. Как и во всем остальном, в XSLT есть несколько способов сделать это, но вы поняли общую идею. XSLT - это обобщенный язык преобразования дерева, в то время как этот язык развертывания оптимизирован для определенного подмножества общих сценариев. Но самое интересное то, что каждое преобразование XDT - это плагин .NET, так что вы можете создавать свои собственные.

<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@*|node()">
  <xsl:copy>           
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>
<xsl:template match="/configuration/appSettings">
  <xsl:copy>
    <xsl:apply-templates select="node()|@*"/>
    <xsl:element name="add">
      <xsl:attribute name="key">NewSetting</xsl:attribute>
      <xsl:attribute name="value">New Setting Value</xsl:attribute>
    </xsl:element>
  </xsl:copy>
</xsl:template>
</xsl:stylesheet>

Или то же самое через преобразование развертывания:

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
   <appSettings>
      <add name="NewSetting" value="New Setting Value" xdt:Transform="Insert"/>
   </appSettings>
</configuration>
person Scott Hanselman    schedule 25.08.2011
comment
О, это мило! У вас есть приложение с множеством файлов конфигурации (log4net, nHibernate, web.config), и не забыть изменить их все было немного больно. Я тоже не ожидал переноса кода в CruiseControl.NET, но, похоже, это тоже несложно. - person DilbertDave; 19.06.2012
comment
К вашему сведению, SlowCheetah было фантастическим расширением, которое теперь не будет поддерживаться после VS 2014. По словам автора, Сайеда Ибрагима Хашими, sedodream.com/2014/08/11/. - person bdeem; 01.10.2014
comment
@AnilNatha Где сказано, что они откажутся от поддержки? - person andrewb; 15.02.2016
comment
@andrewb, я прочитал это здесь; однако это было год назад. После повторного посещения темы и прочтения комментариев, похоже, кто-то предоставил версию, которая работает с VS2015 здесь. - person Anil Natha; 15.02.2016
comment
Отлично работает с Visual Studio 2017 и Visual STudio 2019 - person Guilherme de Jesus Santos; 31.05.2019
comment
Теперь это - person Hugo Freitas; 06.11.2019
comment
Кто-нибудь знает, где взять версию, совместимую с Visual Studio 2010? - person Sphynx; 31.03.2020

Я пробовал несколько решений, и вот самое простое, которое я нашел лично.
Дэн указал в комментариях, что исходное сообщение принадлежит Олегу Сычу - спасибо, Олег!

Вот инструкции:

1. Добавьте в проект XML-файл для каждой конфигурации.

Обычно у вас будут конфигурации Debug и Release, поэтому назовите файлы App.Debug.config и App.Release.config. В своем проекте я создал конфигурацию для каждого типа среды, так что вы можете поэкспериментировать с этим.

2. Выгрузите проект и откройте файл .csproj для редактирования.

Visual Studio позволяет редактировать файлы .csproj прямо в редакторе - вам просто нужно сначала выгрузить проект. Затем щелкните его правой кнопкой мыши и выберите Изменить ‹ProjectName› .csproj.

3. Свяжите файлы конфигурации App. *. Config с основным файлом App.config

Найдите раздел файла проекта, который содержит все ссылки App.config и App.*.config. Вы заметите, что их действия по сборке установлены на None, и это нормально:

<None Include="App.config" />
<None Include="App.Debug.config" />
<None Include="App.Release.config" />

Затем сделайте все специфичные для конфигурации файлы зависимыми от главного App.config, чтобы Visual Studio сгруппировала их так же, как файлы конструктора и файлы кода программной части.

Замените приведенный выше XML на приведенный ниже:

<None Include="App.config" />
<None Include="App.Debug.config" >
  <DependentUpon>App.config</DependentUpon>
</None>
<None Include="App.Release.config" >
  <DependentUpon>App.config</DependentUpon>
</None>

4. Активировать магию преобразований (по-прежнему необходимо для таких версий Visual Studio, как VS2019)

В конце файла после

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

и перед финалом

</Project>

вставьте следующий XML-код - обратите внимание, что для правильного преобразования необходимо выполнить два шага:

  <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
  <Target Name="BeforeBuild" Condition="Exists('App.$(Configuration).config')">
    <!-- Generate transformed app config and replace it: will get the <runtime> node and assembly bindings properly populated -->
    <TransformXml Source="App.config" Destination="App.config" Transform="App.$(Configuration).config" />
  </Target>
  <Target Name="AfterBuild" Condition="Exists('App.$(Configuration).config')">
    <!-- Generate transformed app config in the intermediate directory: this will transform sections such as appSettings -->
    <TransformXml Source="App.config" Destination="$(IntermediateOutputPath)$(TargetFileName).config" Transform="App.$(Configuration).config" />
    <!-- Force build process to use the transformed configuration file from now on.-->
    <ItemGroup>
      <AppConfigWithTargetPath Remove="App.config" />
      <AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config">
        <TargetPath>$(TargetFileName).config</TargetPath>
      </AppConfigWithTargetPath>
    </ItemGroup>
  </Target>

Теперь вы можете перезагрузить проект, собрать его и наслаждаться App.config преобразованиями!

К вашему сведению

Убедитесь, что ваши App.*.config файлы правильно настроены следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
     <!--magic transformations here-->
</configuration>
person Dan Abramov    schedule 24.02.2011
comment
Большое спасибо за это! Одно замечание: если вы добавите новые файлы .config в проект после редактирования csproj, они будут отображаться сгруппированными в App.config. Я добавил одну перед редактированием csproj и, по сути, получил две ссылки на нее, одну сгруппированную и одну соло. - person Jeff Swensen; 20.03.2011
comment
Вы уверены, что удалили все оригинальные <None Include=""/> перед добавлением новых <Content Include=""/>? Эта инструкция срабатывала у меня несколько раз, так что, возможно, вы что-то пропустили. - person Dan Abramov; 21.03.2011
comment
Я удалил все <None>, относящиеся к .config файлам. Нужно ли было делать это и для других ресурсов? - person Jeff Swensen; 21.03.2011
comment
Не думаю. Ну, в любом случае, я полагаю, теперь проблема решена? - person Dan Abramov; 22.03.2011
comment
@gaearon: Большое спасибо; Я искал это некоторое время - хотел бы дать больше одного голоса. - person Aasmund Eldhuset; 10.05.2011
comment
Откуда взялось свойство $(TargetFileName)? Я пытаюсь использовать это для преобразования не только web.config в моем проекте webapp. - person Maslow; 05.07.2011
comment
@Maslow: я думаю, что для проектов Windows он содержит имя выходного файла (например, SampleApp.exe). Следовательно, $(TargetFileName).config становится SampleApp.exe.config, и это именно тот файл, который мы хотели преобразовать. Вам это не понадобится для веб-проекта, потому что у него нет единого имени выходного файла. - person Dan Abramov; 06.07.2011
comment
У меня почти это работает. Файл в папке / obj правильный, но он не копируется в качестве окончательного выходного файла. Я считаю, что это означает, что бит AppConfigWithTargetPath не работает для меня - что я могу сделать? - person Neil Barnwell; 12.08.2011
comment
@Neil: Вы можете попробовать создать новый проект и воспроизвести проблему? - person Dan Abramov; 12.08.2011
comment
Я решил свою проблему, изменив AfterCompile на BeforeCompile, в конце концов. Честно говоря, в этом есть смысл, но я не очень разбираюсь в цепочке команд для процесса сборки. - person Neil Barnwell; 15.08.2011
comment
Одна из проблем этого подхода заключается в том, что когда вы просматриваете вкладку «Опубликовать» в свойствах проекта, а затем нажимаете кнопку «Файлы приложения» ... вы заметите, что app.config, app.Debug.config, app.Release. config принудительно развертываются как часть процесса публикации. Конечно, у вас тоже есть правильный файл MyApp.exe.config, но я не хочу, чтобы этот лишний багаж разворачивался. Должен быть способ сохранить файлы конфигурации app. *. В проекте как ‹None› вместо ‹Content›. - person Lee Grissom; 01.11.2011
comment
При использовании проекта установки и развертывания для развертывания приложения Windows преобразованный файл конфигурации не развертывается. S&D выбирает app.config (переименовывает в AppName.exe.config) и вместо этого развертывает его. Я все еще работаю над тем, как это исправить ... у кого-нибудь есть идеи? - person empo; 15.11.2011
comment
Чтобы добавить к моему предыдущему комментарию, я проверил папки bin и obj, и они содержат правильно преобразованный файл конфигурации, но S&D его не использует. - person empo; 15.11.2011
comment
В имени Target AfterCompile у меня не работал, AfterBuild работал. - person nakhli; 09.04.2012
comment
Отлично работает, это единственное решение с VS Express Edition. - person Łukasz Wiatrak; 04.03.2014
comment
Это все равно должен быть правильный ответ, поскольку вышеупомянутый аддон SlowCheetah кажется нереальным. - person Oliver Weichhold; 01.08.2014
comment
Спасибо, это правильный путь. Я пытался использовать SlowCheetah в нашей команде, но большую часть времени это было нереально. - person MonkeyCoder; 24.10.2014
comment
Ответ лауреата Оскара. Специально вставьте следующий раздел XML. - person MHOOS; 24.03.2015
comment
Это может быть обновлено, чтобы больше не относиться к медленному гепарду из-за его приближающейся кончины. (это также чище IMHO, чем обременение VS другим дополнением.) - person Jon Egerton; 27.04.2015
comment
Не работает для меня, я сделал то же самое, и когда я публикую пакет в виде zip-файла, то внутри этого моего файла app.config никогда не преобразуется. Остается то же самое. - person Rupesh Kumar Tiwari; 23.07.2015
comment
Единственная проблема, которую это упускает для некоторых, - это ответ Олега Сича, который не учитывает ключевой момент. Если в вашем индивидуальном приложении. (Env) .configs вы НЕ указываете конфигурацию '‹xmlns: xdt = schemas.microsoft.com/XML-Document-Transform ›'и что-то вроде‹ appSettings xdt: Transform = Replace ›или атрибутов, которые делают аналогичные вещи в строках настроек, это не будет работать. Эта последняя информация является ключевой, и как только я ее добавил, все заработало. - person djangojazz; 09.10.2015
comment
аааааааааааааааааа ... наконец облегчение !!! FWIW - успешно применил этот ответ к моему проекту VB.NET в V.S. 2015 .. супер просто! - person bkwdesign; 04.05.2016
comment
Вы можете заменить v10.0 на v$(VisualStudioVersion), чтобы убедиться, что ваш проект работает со всеми более поздними версиями VS. - person Thibault D.; 11.05.2016
comment
Я понимаю, что это произошло пятью годами позже, но это все еще кажется лучшим решением с предложением @ ThibaultD. v$(VisualStudioVersion) и без изменения тегов <None /> на <Content /> - person Auspex; 19.07.2016
comment
Не доверяйте мне v$(VisualStudioVersion), я просто скопировал его из этого ответа: stackoverflow.com/a/18075313/2003763 Потому что подумал, что лучше будет как комментарий. - person Thibault D.; 20.07.2016
comment
Одно важное замечание ... не забудьте добавить ‹tagname xdt: Transform = Replace› ... ‹/tagname› внутри тегов файла app.release.config, которые следует использовать для замены параметров отладки. - person matendie; 15.11.2016
comment
В первой строке вы даже можете использовать это выражение $(VSToolsPath)\Web\Microsoft.Web.Publishing.Ta‌​sks.dll вместо этого $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll. - person Rosberg Linhares; 01.03.2017
comment
У меня была ошибка MSBuild error MSB3021: Невозможно скопировать файл. Не удалось найти файл obj \ Release \ ConsoleApp.exe во время сборки. Поэтому я немного изменил решение, чтобы повторно использовать раздел target ‹Target Name = AfterBuild› вместо создания нового подобия в решении. - person asidis; 05.10.2018
comment
Я не тестировал это в более ранних версиях VS, но в 2019 году мне пришлось поставить биты <UsingTask> и <Target> перед существующей целью CSharp. Это было для приложения WPF, но ему не удавалось скомпилировать проект, не распознавая большую часть кода, а также не распознавало какие-либо ссылки проекта на другие проекты в решении. - person David Anderson; 18.04.2019
comment
Ключевым моментом здесь было преобразование типа содержимого, похоже, преобразования не происходят в типе None. - person Kat Lim Ruiz; 26.06.2019
comment
еще один комментарий, это не сработало в Azure Pipelines, то, что я сделал в конце, заключалось в использовании задачи FileTransform, которая применяет то же преобразование, перед построением решения, а также отключением его во всех csprojs. В каком-то смысле это имеет смысл делать во время CI, а также это более прозрачно для процесса сборки. - person Kat Lim Ruiz; 27.06.2019
comment
... В некотором смысле имеет смысл делать во время CI, поскольку это не компиляция как таковая, она также более прозрачна для процесса сборки, и, кроме того, этот вызов TransformXml иногда не компилировался в локальной среде (возможно, смешение версий VS ). - person Kat Lim Ruiz; 27.06.2019
comment
Как указал @KatLimRuiz, лучше сделать это в конвейере выпуска, используя официальный Задача преобразования файлов. Я дал ответ на другой вопрос, в котором конкретно спрашивается, как это сделать в Azure DevOps, и подробно описывается, как это сделать. используя указанную задачу. - person Neo; 17.07.2019
comment
Я просто вернулся к этому снова через несколько лет, и мне хотелось бы снова проголосовать. - person tkit; 23.07.2019
comment
Новичкам больше не нужно все это делать, по крайней мере, в VS2017. Просто измените с None на Content, и вы также можете сделать это: <ItemGroup> <Content Update="App.*.config" DependentUpon="App.config" /> </ItemGroup> вместо добавления к каждой записи App.*.config. - person jpgrassi; 06.09.2019
comment
@jpgrassi Я редактирую ответ, чтобы добавить ваш комментарий - person Esteban Verbel; 09.10.2019
comment
@EstebanVerbel, @jpgrassi: Когда вы говорите, что вам больше не нужно выполнять шаг 4, означает ли это, что вы не включаете цель CoreCompile? Теперь это выполняется автоматически? - person end-user; 23.12.2019
comment
@ end-user Я пробовал без шага 4, но не смог заставить его работать. Я просто включил шаг 4. Я использую VS 2019. - person Andrew; 24.12.2019
comment
По какой-то причине мой не работает. Когда я запускаю отладку, он просто дает мне значения app.config? - person Zapnologica; 11.07.2020
comment
Я использую VS2019, и он будет работать только с включенным шагом 4, но это вызывает ошибки, если вы еще не создали приложение. Если вы удалите папку obj, как будто строите с нуля, вы не сможете построить из-за отсутствия файлов. - person D. Hodge; 22.10.2020
comment
@ D.Hodge. Если вы измените CoreCompile на AfterCompile, он будет работать нормально. - person kb4000; 16.02.2021
comment
На VS19 не забудьте изменить 4-й шаг. От <Target Name="CoreCompile" до <Target Name="AfterCompile". В противном случае это вызовет ошибку сборки: Could not copy the file "obj\Debug\*.exe" because it was not found. - person hastrb; 09.04.2021

Другое решение, которое я нашел, - НЕ использовать преобразования, а просто иметь отдельный файл конфигурации, например. app.Release.config. Затем добавьте эту строку в свой файл csproj.

  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
    <AppConfig>App.Release.config</AppConfig>
  </PropertyGroup>

Это не только создаст правильный файл myprogram.exe.config, но и если вы используете проект установки и развертывания в Visual Studio для создания MSI, это заставит проект развертывания использовать правильный файл конфигурации при упаковке.

person Alec    schedule 18.10.2011
comment
Нерассказанные чудеса MSBuild. Теперь мне интересно, что еще возможно. Кстати. это работает также для развертываний clickonce непосредственно из VS (в отличие от ответов с более высоким рейтингом). - person Boris B.; 15.07.2013
comment
Изменения могут стать обременительными и подверженными ошибкам, если в конфигурациях содержится много записей, которые ОДИНАКОВЫЕ для всех сборок. Решение проблемы прямо сейчас, когда в .config одной среды пропущено изменение, и, конечно же, это была производственная среда. - person jeepwran; 23.02.2015
comment
Наличие двух копий файла конфигурации не проблема, если только разработчики не поддерживают его вручную. - person anIBMer; 26.08.2015
comment
Это красиво, работает как шарм! Я вставил только строку <AppConfig>App.Release.config</AppConfig> в существующее условие <PropertyGroup для конфигурации Release, и IDE показала волнистую линию под строкой _4 _..., говоря, что ее нет в схеме или что-то в этом роде, но я все равно сохранил файл и перезагрузил файл проекта и сделал сборку в Release config, и это сработало! - person Shiva; 03.11.2016
comment
При этом вы потеряете функциональность дизайнера настроек. - person Ondřej; 10.04.2017
comment
Просто дополнение: конечно, вы можете изменить условие, игнорируя платформу (например, если вы создаете Any Platform): <PropertyGroup Condition=" '$(Configuration)' == 'Release' "> - person Ole Albers; 10.07.2019
comment
Это работает (очень легко) и, по-моему, лучший вариант для простых рабочих процессов. - person Jeremy Morren; 27.07.2020
comment
Для простых рабочих процессов - да, так как необходимость многократно клонировать большие файлы конфигурации только для изменения одного значения неосуществима. - person iBobb; 19.03.2021

Вдохновленный Олегом и другими в этом вопросе, я принял решение https://stackoverflow.com/a/5109530/2286801 еще на шаг, чтобы включить следующее.

  • Работает с ClickOnce
  • Работает с проектами установки и развертывания в VS 2010.
  • Работает с VS2010, 2013, 2015 (не тестировал 2012 год, хотя тоже должен работать).
  • Работает с Team Build. (Вы должны установить A) Visual Studio или B) Microsoft.Web.Publishing.targets и Microsoft.Web.Publishing.Tasks.dll)

Это решение работает, выполняя преобразование app.config перед первым обращением к app.config в процессе MSBuild. Он использует файл внешних целей для упрощения управления несколькими проектами.

Инструкции:

Аналогичные шаги для другого решения. Я процитировал то, что осталось прежним, и включил его для полноты и простоты сравнения.

0. Добавьте в проект новый файл под названием AppConfigTransformation.targets.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!-- Transform the app config per project configuration.-->
  <PropertyGroup>
    <!-- This ensures compatibility across multiple versions of Visual Studio when using a solution file.
         However, when using MSBuild directly you may need to override this property to 11.0 or 12.0 
         accordingly as part of the MSBuild script, ie /p:VisualStudioVersion=11.0;
         See http://blogs.msdn.com/b/webdev/archive/2012/08/22/visual-studio-project-compatability-and-visualstudioversion.aspx -->
    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
  </PropertyGroup>

  <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.targets" />

  <Target Name="SetTransformAppConfigDestination" BeforeTargets="PrepareForBuild" 
          Condition="exists('app.$(Configuration).config')">
    <PropertyGroup>
      <!-- Force build process to use the transformed configuration file from now on. -->
      <AppConfig>$(IntermediateOutputPath)$(TargetFileName).config</AppConfig>
    </PropertyGroup>
    <Message Text="AppConfig transformation destination: = $(AppConfig)" />
  </Target>

  <!-- Transform the app.config after the prepare for build completes. -->
  <Target Name="TransformAppConfig" AfterTargets="PrepareForBuild" Condition="exists('app.$(Configuration).config')">
    <!-- Generate transformed app config in the intermediate directory -->
    <TransformXml Source="app.config" Destination="$(AppConfig)" Transform="app.$(Configuration).config" />
  </Target>

</Project>

1. Добавьте в проект XML-файл для каждой конфигурации.

Обычно у вас есть конфигурации отладки и выпуска, поэтому назовите свои файлы App.Debug.config и App.Release.config. В своем проекте я создал конфигурацию для каждого типа среды, так что вы можете поэкспериментировать с этим.

2. Выгрузите проект и откройте файл .csproj для редактирования.

Visual Studio позволяет редактировать .csproj прямо в редакторе - вам просто нужно сначала выгрузить проект. Затем щелкните его правой кнопкой мыши и выберите «Изменить .csproj».

3. Привязать файлы конфигурации App. *. К основному файлу App.config

Найдите раздел файла проекта, содержащий все ссылки на App.config и App. *. Config, и замените его следующим образом. Вы заметите, что мы используем None вместо Content.

<ItemGroup>
  <None Include="app.config"/>
  <None Include="app.Production.config">
    <DependentUpon>app.config</DependentUpon>
  </None>
  <None Include="app.QA.config">
    <DependentUpon>app.config</DependentUpon>
  </None>
  <None Include="app.Development.config">
    <DependentUpon>app.config</DependentUpon>
  </None>
</ItemGroup>

4. Activate transformations magic

В конце файла после

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

и перед финалом

</Project>

вставьте следующий XML:

<Import Project="AppConfigTransformation.targets" />

Выполнено!

person bdeem    schedule 01.10.2014
comment
Пробовал в VS Community 2015 RC, и он игнорирует файл app.Debug.config, который у меня есть. - person Khainestar; 29.10.2015
comment
Я успешно использовал принятый ответ в одном проекте WinForms ... но по какой-то непонятной причине не смог применить принятый ответ. в другой проект WinForms (все в одном решении). Этот ответ от @bdeem - мой новый фаворит, поскольку он правильно взаимодействовал с моим проектом MSI - большое спасибо! - person bkwdesign; 07.12.2016
comment
Похоже, в VS 2015 это не сработало. Я обновил VisualStudioVersion с 10 до 12, но без кубиков. Любые идеи? - person Sinaesthetic; 02.03.2017
comment
@Sinaesthetic Можете дать нам более подробную информацию? VS 2015 Ultimate, Сообщество и т. Д. VB.NET, C #, есть ошибки? - person bdeem; 08.03.2017
comment
VS2015 Enterprise. Никаких ошибок. Он просто ничего не делает. - person Sinaesthetic; 08.03.2017
comment
1) Убедитесь, что вы включили файл как часть проекта. Действие сборки = Нет. 2) Проверьте свой файл преобразования. Возможно, преобразование неверное. - person bdeem; 15.03.2017
comment
Привет, я попытался выполнить вышеупомянутые шаги в моем типе проекта VSTO, но, к сожалению, мне не удалось получить преобразования в моем основном файле app.config. Кстати, я мог видеть, что он создал файл конфигурации как App.config.deploy. Я что-то упускаю или делаю неправильно - вот мой файл конфигурации и файл проекта CS (gist.github .com / Ganeshcse / f3a7369d93b6b06923e9aa848682fa06) - person G K; 04.04.2017

По моему опыту, вещи, которые мне нужно сделать зависящими от среды, - это такие вещи, как строки подключения, настройки приложений и часто настройки smpt. Система конфигурации позволяет указывать эти вещи в отдельных файлах. Таким образом, вы можете использовать это в своем app.config / web.config:

 <appSettings configSource="appsettings.config" />
 <connectionStrings configSource="connection.config" />
 <system.net>
    <mailSettings>
       <smtp configSource="smtp.config"/>
    </mailSettings>
 </system.net>

Обычно я помещаю эти разделы, относящиеся к конфигурации, в отдельные файлы, во вложенную папку с именем ConfigFiles (в зависимости от того, в корне решения или на уровне проекта). Я определяю файл для каждой конфигурации, например smtp.config.Debug и smtp.config.Release.

Затем вы можете определить событие перед сборкой следующим образом:

copy $(ProjectDir)ConfigFiles\smtp.config.$(ConfigurationName) $(TargetDir)smtp.config

В командной разработке вы можете настроить это дальше, включив в соглашение% COMPUTERNAME% и / или% USERNAME%.

Конечно, это означает, что целевые файлы (x.config) НЕ следует помещать в систему управления версиями (поскольку они создаются). Вы все равно должны добавить их в файл проекта и установить для их свойства типа вывода значение «всегда копировать» или «копировать, если новее».

Простой, расширяемый и работает для всех типов проектов Visual Studio (консоль, winforms, wpf, веб).

person jeroenh    schedule 12.02.2011
comment
У меня точно такая же конфигурация, что и у вас. Но у меня проблемы с преобразованием файла smtp. Можете ли вы включить оригинал и трансформацию? Это мои: Базовый файл: <?xml version="1.0"?> <smtp deliveryMethod="SpecifiedPickupDirectory"> <specifiedPickupDirectory pickupDirectoryLocation="C:\mail"/> <network host="localhost"/> </smtp> Преобразование: <?xml version="1.0"?> <smtp xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform" xdt:Transform="Replace" from="[email protected]" deliveryMethod="Network"> <network .../> </smtp> - person jgarza; 25.11.2013
comment
Я не уверен, что понимаю. В этой конфигурации я ничего не трансформирую, просто копирую файлы ... - person jeroenh; 26.11.2013
comment
О, я не видел копию. Я трансформирую конфиг, а не просто копирую его. Спасибо, в любом случае. - person jgarza; 26.11.2013
comment
Мне нравится это решение. Одно небольшое предложение: в приведенном выше примере копии исходный и целевой аргументы для копирования должны быть заключены в кавычки; в противном случае предварительная сборка не удастся для каталогов, в имени которых есть пробел. - person vandre; 25.06.2016

Вы можете использовать отдельный файл конфигурации для каждой конфигурации, например app.Debug.config, app.Release.config, а затем используйте переменную конфигурации в файле проекта:

<PropertyGroup>
    <AppConfig>App.$(Configuration).config</AppConfig>
</PropertyGroup>

Затем будет создан правильный файл ProjectName.exe.config в зависимости от конфигурации, которую вы создаете.

person Tevin    schedule 02.07.2012
comment
Спасибо, я не использовал ваш точный пример для решения возникшей у меня проблемы, но ваш пример заставил меня задуматься и привел к еще одной очень похожей ситуации с использованием задачи копирования. - person jpierson; 08.11.2012
comment
Пробовал это в VS 2015 Community RC, и он строит, но затем игнорирует содержимое приложения. *. Config, которое я добавил. - person Khainestar; 29.10.2015

Я написал красивое расширение для автоматизации преобразования app.config, подобное встроенному в проект веб-приложения Преобразование конфигурации

Самым большим преимуществом этого расширения является то, что вам не нужно устанавливать его на всех сборочных машинах.

person Golan Avraham    schedule 27.05.2012
comment
Очень полезное расширение, особенно сейчас, когда Slow Cheetah переходит в режим обслуживания и может не поддерживаться в будущем. - person dthrasher; 27.02.2015
comment
Да, люди должны перестать замедлять Cheetah в качестве решения этой проблемы, когда эта функция теперь поддерживается задачей transformxml msbuild. Архитектор SW из моей команды чрезмерно усердно ввел медленный гепард в наш проект и создал преобразования отладки, стадии и выпуска для всех наших конфигураций, большинство из которых не нуждались в преобразовании. Излишне говорить, что в тот момент, когда он ушел, я вытащил медленного гепарда, и теперь мы просто используем одну задачу transformxml в web.config. Аааа, простота. Нельзя сказать, что медлительному гепарду не было своего времени и места. - person HarryTuttle; 28.04.2016

Установите «Инструмент преобразования конфигурации» в Visual Studio из Marketplace и перезапустите VS. Вы также сможете увидеть преобразование предварительного просмотра меню для app.config.

https://marketplace.visualstudio.com/items?itemName=GolanAvraham.ConfigurationTransform

person Agnel Amodia    schedule 13.02.2018
comment
Это работает отлично и требует очень мало усилий или размышлений. Очень признателен. Благодарю. («предварительное преобразование» не работает, но «добавить преобразования» отлично работает без проблем в VS 2017). Также, кажется, часто обновляется. - person adudley; 05.09.2018
comment
Большое спасибо за решение, за кулисами, оно делает именно то, что Дэн Абрамов объяснил выше, не пачкая вам руки - person Mohammed Dawood Ansari; 19.11.2018
comment
Это окончательное решение. Предварительный просмотр, похоже, отлично работает с VS 2019. - person Kyle; 07.06.2019
comment
Мне это нравится, но я обнаружил, что он не поддерживает другие файлы, отличные от app.config, без некоторого редактирования csproj. Тем не менее, приятно видеть превью. - person Ian1971; 17.03.2020

Небольшое улучшение решения, которое сейчас, кажется, публикуется повсюду:

<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
  • то есть, если вы не планируете навсегда оставаться с текущей версией VS
person Yuri Makassiouk    schedule 06.08.2013
comment
Не могли бы вы объяснить свой ответ немного или дать источники, чтобы объяснить это? - person roydukkey; 21.08.2013
comment
Не похоже, что $(VisualStudioVersion) установлен при прямом использовании MSBuild. - person Jeremy Smith; 23.10.2013
comment
Это должен быть комментарий к stackoverflow.com/a/5109530/2003763 (я только что добавил ту же информацию, что и комментарий там) - person Thibault D.; 11.05.2016

Так что в итоге я выбрал немного другой подход. Я выполнил шаги Дэна через шаг 3, но добавил еще один файл: App.Base.Config. Этот файл содержит параметры конфигурации, которые вы хотите использовать в каждом сгенерированном App.Config. Затем я использую BeforeBuild (с добавлением Юрия к TransformXml), чтобы преобразовать текущую конфигурацию с базовой конфигурацией в файл App.config. Затем процесс сборки использует преобразованный файл App.config как обычно. Тем не менее, одна неприятность заключается в том, что вы как бы хотите исключить постоянно меняющийся App.config из системы управления версиями впоследствии, но другие файлы конфигурации теперь зависят от него.

  <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
  <Target Name="BeforeBuild" Condition="exists('app.$(Configuration).config')">
    <TransformXml Source="App.Base.config" Transform="App.$(Configuration).config" Destination="App.config" />
  </Target>
person Waggles    schedule 29.10.2014

Я создал другую альтернативу тому, что опубликовал Вишал Джоши, в котором снято требование изменить действие сборки на Content, а также реализована базовая поддержка развертывания ClickOnce. Я говорю «базовый», потому что я не тестировал его полностью, но он должен работать в типичном сценарии развертывания ClickOnce.

Решение состоит из одного проекта MSBuild, который после импорта в существующий проект приложения Windows (* .csproj) расширяет процесс сборки, чтобы предусмотреть преобразование app.config.

Вы можете прочитать более подробное объяснение на странице Visual Studio App.config XML Transformation и файл проекта MSBuild можно загрузить с GitHub.

person João Angelo    schedule 22.06.2010

Если вы используете TFS онлайн (облачная версия) и хотите преобразовать App.Config в проекте, вы можете сделать следующее, не устанавливая никаких дополнительных инструментов. Из VS => Выгрузить проект => Редактировать файл проекта => Перейти в конец файла и добавить следующее:

<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="AfterBuild" Condition="Exists('App.$(Configuration).config')">
<TransformXml Source="App.config" Transform="App.$(Configuration).config" Destination="$(OutDir)\$(AssemblyName).dll.config" />

AssemblyFile и Destination работают для локального использования и для онлайн-сервера TFS (облачного).

person Benjamin    schedule 18.03.2015

Предлагаемое решение не будет работать, если на библиотеку классов с файлом конфигурации ссылается другой проект (в моем случае это была библиотека рабочего проекта Azure). Он не скопирует корректный преобразованный файл из папки obj в папку bin\##configuration-name##. Чтобы он работал с минимальными изменениями, вам нужно изменить AfterCompile target на BeforeCompile:

<Target Name="BeforeCompile" Condition="exists('app.$(Configuration).config')">
person avs099    schedule 06.10.2016

Примечание. Из-за репутации я не могу комментировать bdeem сообщение. Вместо этого я публикую свои выводы в качестве ответа.

После bdeem сообщения, я сделал следующее (по порядку):

1. Я модифицировал [project].csproj файл. Добавлены теги <Content Include="" /> в ItemGroup для различных config файлов и поставлены в зависимость от исходного config файла.

Примечание. Использование <None Include="" /> не работает с преобразованием.

<!-- App.config Settings -->
<!-- Create App.($Configuration).config files here. -->
<Content Include="App.config" />
<Content Include="App.Debug.config">
  <DependentUpon>App.config</DependentUpon>
</Content>
<Content Include="App.Release.config">
  <DependentUpon>App.config</DependentUpon>
</Content>

2. Внизу файла [project].csproj (перед закрывающим тегом </Project>) я импортировал файл ${MSBuildToolsPath\Microsoft.CSharp.targets, добавил UsingTask для преобразования XML и добавил Target, чтобы скопировать преобразованный файл App.config в место вывода.

Примечание: Target также перезапишет App.Config в локальном каталоге, чтобы сразу увидеть изменения, работающие локально. Target также использует свойство Name="Afterbuild", чтобы файлы конфигурации можно было преобразовать после создания исполняемых файлов. По непонятным мне причинам при использовании конечных точек WCF, если я использую Name="CoreCompile", я получаю предупреждения об атрибутах службы. Name="Afterbuild" решил это.

  <!-- Task to transform the App.config using the App.($Configuration).config file. -->
  <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />

  <!-- Only compile the App.config if the App.($Configuration).config file exists. -->
  <!-- Make sure to use the AfterBuild name instead of CoreCompile to avoid first time build errors and WCF endpoint errors. -->
  <Target Name="AfterBuild" Condition="exists('App.$(Configuration).config')">
    <!-- Generate transformed App.config in the intermediate output directory -->    
    <TransformXml Source="App.config" Destination="$(IntermediateOutputPath)$(TargetFileName).config" Transform="App.$(Configuration).config" />
    
    <!-- Modify the original App.config file with the transformed version. -->
    <TransformXml Source="App.config" Destination="App.config" Transform="App.$(Configuration).config" />

    <!-- Force build process to use the transformed configuration file from now on. -->
    <ItemGroup>
      <AppConfigWithTargetPath Remove="App.config" />
      <AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config">
        <TargetPath>$(TargetFileName).config</TargetPath>
      </AppConfigWithTargetPath>
    </ItemGroup>
  </Target>
</Project>

3. Вернулся в Visual Studio и перезагрузил измененные файлы.

4. Вручную добавил в проект App.*.config файлы. Это позволило им сгруппироваться под исходным App.config файлом.

Примечание. Убедитесь, что файлы App.*.config имеют правильную структуру XML.

<?xml version="1.0" encoding="utf-8"?>

<!-- For more information on using web.config transformation visit https://go.microsoft.com/fwlink/?LinkId=125889 -->

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <connectionStrings>
    <add name="myConn" connectionString=""; Initial Catalog=; User ID=; Password=;" xdt:Transform="SetAttributes" xdt:Locator="Match(name)" />
  </connectionStrings>
</configuration>

5. Перестроил проект.

person Sparky    schedule 04.11.2020