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

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

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

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

Ответы [ 14 ]

529 голосов
/ 24 февраля 2011

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

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

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

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

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

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

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

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

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

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

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

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

4.Активируйте магию преобразований

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

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

и перед окончательным

</Project>

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

  <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
  <Target Name="CoreCompile" Condition="exists('app.$(Configuration).config')">
    <!-- Generate transformed app config in the intermediate directory -->
    <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 преобразованиями!

FYI

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

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
     <!--magic transformations here-->
</configuration>
403 голосов
/ 25 августа 2011

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

Вы можетенажмите на свой web.config и нажмите «Добавить преобразования конфигурации».Когда вы сделаете это, вы получите web.debug.config и web.release.config.Вы можете создать web.whwhat.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>
127 голосов
/ 18 октября 2011

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

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

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

33 голосов
/ 12 февраля 2011

По моему опыту, вещи, которые мне нужно сделать для конкретной среды, это такие вещи, как строки подключения, настройки приложений и часто игнорируемые настройки. Система конфигурации позволяет указывать эти вещи в отдельных файлах. Так что вы можете использовать это в вашем 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 (console, winforms, wpf, web).

28 голосов
/ 02 октября 2014

Вдохновленный Олегом и другими в этом вопросе, я принял решение 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 для каждой конфигурации в проект.

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

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

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

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

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

<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.Активируйте магию преобразований

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

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

и перед окончательным

</Project>

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

<Import Project="AppConfigTransformation.targets" />

Готово!

27 голосов
/ 02 июля 2012

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

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

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

13 голосов
/ 27 мая 2012

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

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

4 голосов
/ 30 октября 2014

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

3 голосов
/ 13 февраля 2018

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

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

3 голосов
/ 06 августа 2013

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

<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
  • то есть, если вы не планируете оставаться с текущей версией VS навсегда
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...