575 votes

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

Pour Visual Studio 2010 Web-based application nous avons Config Transformation fonctionnalités par lequel nous pouvons maintenir plusieurs fichiers de configuration pour les différents environnements. Mais la même fonctionnalité n'est pas disponible pour les fichiers App.Config pour les services Windows/WinForms ou l'application console.

Il existe une solution de contournement, comme suggéré ici : Appliquer la magie XDT à App.Config .

Cependant, ce n'est pas simple et cela nécessite un certain nombre d'étapes. Existe-t-il un moyen plus simple d'obtenir la même chose pour les fichiers app.config ?

0 votes

Je suis tombé sur l'article suivant qui semble un peu plus simple mais je ne l'ai pas essayé moi-même. fknut.blogspot.com/2009/11/ Il y a également une demande de fonctionnalité sur MS Connect qui pourrait valoir la peine d'être votée pour qu'elle soit incluse dans le prochain SP ou la prochaine version. connect.microsoft.com/VisualStudio/feedback/details/564414

625voto

Dan Points 16670

Mise à jour

Cette réponse est quelque peu dépassée. Je vais la laisser pour l'histoire et les personnes qui préfèrent ne pas utiliser de modules complémentaires pour une raison quelconque. Veuillez vous référer à Réponse de Scott à moins que vous ne sachiez ce que vous faites.


J'ai essayé plusieurs solutions, et voici la plus simple que j'ai trouvée.
Dan a souligné dans les commentaires que le billet original appartient à Oleg Sych - Merci, Oleg !

Voici les instructions :

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

En général, vous aurez Debug et Release donc nommez vos fichiers App.Debug.config et App.Release.config . Dans mon projet, j'ai créé une configuration pour chaque type d'environnement, vous pouvez donc l'expérimenter.

2. Déchargez le projet et ouvrez le fichier .csproj pour le modifier.

Visual Studio vous permet de modifier .csproj directement dans l'éditeur - vous devez juste décharger le projet avant. Ensuite, cliquez avec le bouton droit de la souris sur le projet et sélectionnez Modifier le fichier <Nom du projet>.csproj .

3. Lier les fichiers App.*.config à l'App.config principal

Trouvez la section du fichier du projet qui contient tous les App.config et App.*.config références. Vous remarquerez que leurs actions de construction sont réglées sur None :

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

Tout d'abord, définissez une action de construction pour chacun d'entre eux pour Content .
Ensuite, faites en sorte que tous les Configuration spécifique fichiers personne à charge sur le principal App.config afin que Visual Studio les regroupe comme il le fait pour les fichiers de conception et de codebehind.

Remplacez le XML ci-dessus par celui ci-dessous :

<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 la magie des transformations

En fin de dossier après

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

et avant la finale

</Project>

insérer le XML suivant :

  <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
  <Target Name="AfterCompile" 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 en profiter. App.config transformations !

4 votes

Merci beaucoup pour ce travail ! Une remarque : si vous ajoutez les nouveaux fichiers .config au projet après avoir modifié le csproj, ils apparaîtront groupés sous App.config. J'en ai ajouté un avant d'éditer le csproj et je me suis retrouvé avec deux liens vers lui, un groupé et un solo.

0 votes

Êtes-vous sûr d'avoir retiré tous les originaux <None Include=""/> avant d'ajouter de nouvelles <Content Include=""/> s ? Cette instruction a fonctionné pour moi à plusieurs reprises, alors peut-être avez-vous manqué quelque chose.

0 votes

J'ai enlevé tous les <None> liés à .config fichiers. Devais-je le faire aussi pour les autres ressources ?

424voto

Scott Hanselman Points 13109

Cela fonctionne maintenant avec le Visual Studio AddIn traité dans cet article : SlowCheetah - La syntaxe de transformation de Web.config est maintenant généralisée pour tout fichier de configuration XML .

0 votes

Oh, c'est mignon ! J'ai une application avec de nombreux fichiers de configuration (log4net, nHibernate, web.config) et me souvenir de les modifier tous était un peu pénible. Je n'avais pas non plus envie de transférer le code dans CruiseControl.NET, mais on dirait que c'est un jeu d'enfant.

10 votes

FYI, SlowCheetah était une extension fantastique qui ne sera plus supportée après VS 2014. Par l'auteur, Sayed Ibrahim Hashimi, sedodream.com/2014/08/11/… .

0 votes

@AnilNatha Où est-il dit qu'ils vont abandonner le support ?

145voto

Alec Points 501

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.Release.config. Ensuite, ajoutez cette ligne à votre fichier csproj.

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

Cela va non seulement générer le bon fichier myprogram.exe.config, mais si vous utilisez Setup and Deployment Project dans Visual Studio pour générer des MSI, cela forcera le projet de déploiement à utiliser le bon fichier de configuration lors de l'emballage.

6 votes

Les merveilles inouïes de MSBuild. Maintenant je me demande ce qui est encore possible. Btw. cela fonctionne aussi pour les déploiements en clickonce directement depuis VS (contrairement aux réponses les plus votées).

5 votes

Les modifications peuvent devenir onéreuses et sujettes à erreurs si les configurations contiennent de nombreuses entrées qui sont les MÊMES pour toutes les constructions. Je suis actuellement confronté à un problème où le .config d'un environnement a manqué un changement, et bien sûr, il s'agissait de la production.

1 votes

Avoir deux copies du fichier de configuration n'est pas un problème, tant que les développeurs ne sont pas ceux qui le maintiennent manuellement.

35voto

jeroenh Points 12777

D'après mon expérience, les éléments que je dois rendre spécifiques à l'environnement sont des choses comme les chaînes de connexion, les appsettings 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 utiliser ceci dans votre app.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, c'est de placer ces sections spécifiques à la configuration dans des fichiers séparés, dans un sous-dossier appelé ConfigFiles (soit dans la racine de la solution, soit au niveau du projet, cela dépend). Je définis un fichier par configuration, par exemple smtp.config.Debug et smtp.config.Release.

Vous pouvez alors définir un événement de pré-construction comme suit :

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

Dans le cadre d'un développement en équipe, vous pouvez affiner ce principe en incluant le %COMPUTERNAME% et/ou le %USERNAME% dans la convention.

Bien entendu, cela implique que les fichiers cibles (x.config) ne doivent PAS être placés dans le contrôle de la source (puisqu'ils sont générés). Vous devez néanmoins les ajouter au fichier de projet et définir leur propriété de type de sortie sur "copy always" ou "copy if newer".

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

0 votes

J'ai exactement la même configuration que vous. Mais j'ai des problèmes pour transformer le fichier smtp. Pouvez-vous inclure l'original et la transformation ? Voici les miens : Le fichier de base : <?xml version="1.0"?> <smtp deliveryMethod="SpecifiedPickupDirectory"> <specifiedPickupDirectory pickupDirectoryLocation="C:\mail"/> <network host="localhost"/> </smtp> La transformation : <?xml version="1.0"?> <smtp xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transfo‌​rm" xdt:Transform="Replace" from="user@email.com" deliveryMethod="Network"> <network .../> </smtp>

0 votes

Je ne suis pas sûr de comprendre. Dans cette configuration, je ne transforme rien, je ne fais que copier des fichiers...

0 votes

Oh, je n'ai pas vu la partie copie. Je transforme la configuration au lieu de simplement la copier. Merci quand même.

30voto

Tevin Points 676

Vous pouvez utiliser un fichier de configuration distinct par configuration, par exemple app.Debug.config, app.Release.config, puis utiliser la variable de configuration dans votre fichier de projet :

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

Ceci créera alors le fichier ProjectName.exe.config correct selon la configuration dans laquelle vous construisez.

0 votes

Merci, je n'ai pas utilisé votre exemple exact pour résoudre le problème que j'avais mais votre exemple m'a fait réfléchir et m'a conduit à une autre solution très similaire utilisant la tâche de copie.

0 votes

J'ai essayé cela sous VS 2015 Community RC et il se construit, mais ignore ensuite le contenu de l'app.*.config que j'ai ajouté.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X