App.Transformation de Config pour des projets qui ne sont pas des projets Web dans Visual Studio?

pour L'application Web Visual Studio 2010, nous avons des fonctionnalités de Transformation de configuration qui nous permettent de gérer plusieurs fichiers de configuration pour différents environnements. Mais la même fonctionnalité n'est pas disponible pour l'Application.Fichiers de configuration pour Windows Services / WinForms ou Application Console.

il y a une solution de contournement disponible comme suggéré ici: appliquer la magie XDT à App.Config .

cependant, il n'est pas simple et nécessite un certain nombre de mesures. Est-il un moyen plus facile d'obtenir le même pour app.les fichiers de configuration?

490
demandé sur Amitabh 2010-06-09 12:38:01

15 réponses

cela fonctionne maintenant avec le Studio visuel AddIn traité dans cet article: SlowCheetah - Web.la syntaxe de Transformation de configuration est maintenant généralisée pour tout fichier de configuration XML .

vous pouvez faire un clic droit sur votre site.config et cliquez sur " Ajouter une configuration Transformer."Quand tu feras ça, tu auras une toile.débogage.config et un Web.publier.config. Vous pouvez faire un site web.quoi.la configuration, si vous le souhaitez, comme tant que le nom s'aligne avec une configuration profil. Ces fichiers sont seulement les changements que vous voulez faire, non pas une copie complète de votre Web.config.

vous pourriez penser que vous voudriez utiliser XSLT pour transformer un web.config, mais bien qu'ils se sentent intuitivement bien, c'est en fait très verbeux.

voici deux transformations, l'Une utilisant XSLT et la même utilisant le XML Document de Transformation de la syntaxe/espace de noms. Comme pour toutes les choses il y a plusieurs façons de le faire dans XSLT, mais vous obtenez l'idée générale. XSLT est un langage de transformation d'arbre généralisé, alors que ce déploiement l'un est optimisé pour un sous-ensemble spécifique de scénarios courants. Mais, l' la partie cool est que chaque transformation XDT est un plugin .NET, donc vous pouvez faire vôtre.

<?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>

ou la même chose via la transformation de déploiement:

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
   <appSettings>
      <add name="NewSetting" value="New Setting Value" xdt:Transform="Insert"/>
   </appSettings>
</configuration>
394
répondu Scott Hanselman 2016-10-06 09:35:31

j'ai essayé plusieurs solutions et voici le plus simple que j'ai personnellement trouvé.

Dan a souligné dans les commentaires que le post original appartient à Oleg Sych - merci, Oleg!

Voici les instructions:

1. Ajouter un fichier XML pour chaque configuration au projet.

typiquement vous aurez Debug et Release configurations ainsi nommer vos fichiers App.Debug.config et App.Release.config . Dans mon projet, j'ai créé une configuration pour chaque type d'environnement, de sorte que vous pouvez expérimenter avec cela.

2. Déchargez le projet et ouvrez .fichier csproj pour l'édition

Visual Studio vous permet d'éditer .csproj dossiers droit dans l'éditeur-vous venez besoin de décharger le premier projet. Puis cliquez sur le bouton droit de la souris et sélectionnez éditer .csproj .

3. Bind App.*.fichiers de configuration vers L'application principale.config

trouver la section" dossier de projet "qui contient toutes les références App.config et App.*.config . Vous remarquerez que leurs actions de construction sont définies à None :

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

d'abord, mettez construire l'action pour chacun d'eux à Content .

Ensuite, faites tout spécifique à la configuration fichiers dépendant sur le principal App.config donc Visual Studio les regroupe comme il le fait designer et les fichiers de code-derrière.

remplacer XML ci-dessus par le suivant:

<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. Activer les transformations magiques

à la fin du fichier après

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

et avant final

</Project>

insérer le XML suivant:

  <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>

Maintenant vous pouvez recharger le projet, le construire et profiter des transformations App.config !

FYI

assurez-vous que vos fichiers App.*.config ont la bonne configuration comme ceci:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
     <!--magic transformations here-->
</configuration>
503
répondu Dan Abramov 2018-09-10 18:51:58

une autre solution que j'ai trouvée est de ne pas utiliser les transformations mais d'avoir un fichier de configuration séparé, par exemple app.Publier.config. Ensuite, ajoutez cette ligne à votre fichier csproj.

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

cela ne générera pas seulement le bon myprogram.EXE.fichier de configuration mais si vous utilisez le projet de configuration et de déploiement dans Visual Studio pour générer MSI, cela forcera le projet de déploiement à utiliser le bon fichier de configuration lors de l'empaquetage.

119
répondu Alec 2011-10-18 18:12:55

d'après mon expérience, les choses que j'ai besoin de faire spécifiques à l'environnement sont des choses comme les chaînes de connexion, les applications et souvent les paramètres smpt. Le système de configuration permet de spécifier ces choses dans des fichiers séparés. Vous pouvez donc l'utiliser dans votre application.config / web.config:

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

ce que je fais généralement est de mettre ces sections spécifiques à la configuration dans des fichiers séparés, dans un sous-dossier appelé ConfigFiles (soit dans la solution root ou au niveau du projet, dépend). Je définissez un fichier par configuration, par exemple smtp.config.Debug et smtp.config.Publier.

alors vous pouvez définir un événement pré-construction comme ceci:

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

dans le développement d'équipe, vous pouvez encore modifier cela en incluant le %COMPUTERNAME% et/ou le %USERNAME% dans la convention.

bien sûr, cela implique que les fichiers cibles (X. config) ne doit pas être mis en contrôle source (car ils sont générés). Vous devez encore les ajouter à la dossier de projet et de définir leur propriété de type de sortie à 'copier toujours' ou 'Copier si plus récent' cependant.

Simple, extensible, et il fonctionne pour tous les types de projets de Studio visuel (console, winforms, wpf, web).

31
répondu jeroenh 2012-05-09 20:27:52

vous pouvez utiliser un fichier de configuration séparé par configuration, par exemple app.Débogage.config, app.Publier.config puis utiliser la variable de configuration dans votre fichier de projet:

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

cela créera alors le nom de projet correct.EXE.fichier de configuration en fonction de la configuration du bâtiment.

26
répondu Tevin 2012-07-02 09:32:53

inspiré par Oleg et d'autres dans cette question, j'ai pris la solution https://stackoverflow.com/a/5109530/2286801 un pas de plus pour permettre ce qui suit.

  • Fonctionne avec ClickOnce
  • fonctionne avec des projets D'installation et de déploiement dans VS 2010
  • fonctionne avec VS2010, 2013, 2015 (n'a pas testé 2012 mais devrait fonctionner aussi).
  • Travaille avec l'Équipe de Construction. (Vous devez installer A) Visual Studio ou B) Microsoft.Web.Publier.targets et Microsoft.Web.Publier.Tâche.dll)

Cette solution fonctionne en exécutant l'application.transformation de la configuration avant l'application.config est référencé pour la première fois dans le processus MSBuild. Il utilise un fichier cible externe pour faciliter la gestion de plusieurs projets.

Instructions:

étapes similaires à l'autre solution. J'ai cité ce qui reste le même et l'ai inclus pour l'exhaustivité et la comparaison plus facile.

0. Ajoutez un nouveau fichier à votre projet appelé AppConfigTransformation.cibles

<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. Ajouter un fichier XML pour chaque configuration au projet.

typiquement, vous aurez des configurations de débogage et de publication alors nommez vos fichiers App.Débogage.de configuration et d'Application.Publier.config. Dans mon projet, j'ai créé une configuration pour chaque type d'environnement donc vous pourriez vouloir expérimenter avec cela.

2. Déchargez le projet et ouvrez .fichier csproj pour l'édition

Visual Studio vous permet de modifier .csproj droit dans l'éditeur, vous avez juste besoin de décharger le premier projet. Puis cliquez-droit dessus et sélectionnez Modifier .csproj.

3. Bind App.*.fichiers de configuration vers L'application principale.config

trouvez la section project file qui contient toutes les applications.de configuration et d'Application.*.config references et remplacer comme suit. Vous remarquerez que nous n'utilisons aucun contenu au lieu du contenu.

<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. Activer les transformations magiques

à la fin du fichier après

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

et avant final

</Project>

insérer le XML suivant:

<Import Project="AppConfigTransformation.targets" />

fait!

23
répondu bdeem 2017-05-23 11:33:27

j'ai écrit nice extension pour automatiser app.transformation de configuration comme celle intégrée dans le projet D'Application Web transformation de Configuration

le plus grand avantage de cette extension est que vous n'avez pas besoin de l'installer sur toutes les machines de construction

12
répondu Golan Avraham 2012-05-27 07:59:44

je suis tombé sur l'article suivant qui semble un peu plus simple, mais je ne l'ai pas essayé moi-même.

http://fknut.blogspot.com/2009/11/appconfig-transformation-with-new.html

en outre, il ya une demande de fonctionnalité sur MS Connect qui pourrait être intéressant de voter afin que ce soit inclus dans l'ensemble dans la prochaine version SP ou.

https://connect.microsoft.com/VisualStudio/feedback/details/564414

5
répondu Kim R 2010-06-14 10:56:05

Je résous ce problème avec cet outil http://ctt.codeplex.com / . Je l'utilise avec le script CCNet/nAnt pour faire des paquets.

3
répondu outcoldman 2010-08-26 20:19:41

juste une petite amélioration à la solution qui semble être affichée partout maintenant:

<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
  • c'est-à-dire, sauf si vous prévoyez de rester avec votre version VS actuelle pour toujours
3
répondu Yuri Makassiouk 2013-08-06 08:34:53

donc j'ai fini par adopter une approche légèrement différente. J'ai suivi les pas de Dan à l'étape 3, mais j'ai ajouté un autre fichier: App.Base.Config. Ce fichier contient les paramètres de configuration que vous voulez dans chaque application générée.Config. Ensuite, J'utilise BeforeBuild (avec L'ajout de Yuri à TransformXml) pour transformer la configuration actuelle avec la configuration de Base dans L'application.config. Le processus de construction utilise alors L'application transformée.config comme normal. Cependant, un ennui que vous souhaitez exclure de l' application en constante évolution.config à partir du contrôle source par la suite, mais les autres fichiers de config en dépendent maintenant.

  <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>
3
répondu Waggles 2014-10-29 22:05:30

j'ai créé une autre alternative à celle affichée par Vishal Joshi où l'exigence de changer l'action de construction en contenu est supprimée et également mis en œuvre un support de base pour le déploiement de ClickOnce. Je dis basique, parce que je ne l'ai pas testé à fond mais ça devrait marcher dans le scénario de déploiement ClickOnce typique.

la solution consiste en un seul projet MSBuild qui une fois importé à un existant projet d'application windows (*.csproj) étend le processus de construction pour envisager l'application.transformation de configuration.

vous pouvez lire une explication plus détaillée à App studio visuel.la Transformation de config XML et le fichier de projet MSBuild peuvent être téléchargés à partir de GitHub .

2
répondu João Angelo 2010-06-22 15:59:42

si vous utilisez un TFS online(version Cloud) et que vous souhaitez transformer l'application.Config dans un projet, vous pouvez faire ce qui suit sans installer d'outils supplémentaires. VS => Décharger le projet => Modifier le fichier de projet => Allez à la fin du fichier et ajoutez le texte suivant:

<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 et la Destination des œuvres pour une utilisation locale et de la TSF en ligne(Cloud) serveur.

1
répondu Benjamin 2015-03-18 09:28:03

Install "Configuration Transform Tool" in Visual Studio from Marketplace and restart VS. Vous pourrez voir le menu preview transformer pour app.config.

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

1
répondu Agnel Amodia 2018-02-13 21:41:46

la solution proposée ne fonctionnera pas quand une bibliothèque de classe avec fichier de configuration est référencée à partir d'un autre projet (dans mon cas C'était Azure worker project library). Il ne copiera pas correctement le fichier transformé du dossier obj dans le dossier bin\##configuration-name## . Pour que cela fonctionne avec des changements minimes, vous devez changer AfterCompile cible en BeforeCompile :

<Target Name="BeforeCompile" Condition="exists('app.$(Configuration).config')">
0
répondu avs099 2016-10-06 18:57:37