Visual StudioのWebプロジェクトではないプロジェクトのApp.Config変換?


546

Visual Studio 2010 Webベースのアプリケーションの場合、さまざまな環境の複数の構成ファイルを維持できる構成変換機能があります。ただし、同じ機能は、Windowsサービス/ WinFormsまたはコンソールアプリケーションのApp.Configファイルでは使用できません。

ここで推奨されている回避策があります:App.ConfigにXDTマジックを適用します

ただし、これは簡単ではなく、いくつかの手順が必要です。app.configファイルに対して同じことを達成する簡単な方法はありますか?


少しシンプルに見える次の記事を見つけましたが、自分では試していません。fknut.blogspot.com/2009/11/…また、MS Connectに投票する価値のある機能のリクエストがあり、これが次のSPまたはバージョンに全面的に含まれるようにします。connect.microsoft.com/VisualStudio/feedback/details/564414
Kim R

回答:


413

これは、この記事で扱われているVisual Studioアドインで機能します

web.configを右クリックして、[構成変換の追加]をクリックします。これを行うと、web.debug.configとweb.release.configが取得されます。名前が構成プロファイルと一致する限り、必要に応じてweb.whatever.configを作成できます。これらのファイルは、Web.configの完全なコピーではなく、必要な変更にすぎません。

XSLTを使用してweb.configを変換したいと思うかもしれませんが、それらは直感的に正しいと感じていますが、実際には非常に冗長です。

2つの変換があります。1つはXSLTを使用し、もう1つは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>

ああ、甘い!多数の構成ファイル(log4net、nHibernate、web.config)を含むアプリを用意し、それらすべてを変更することを思い出すのは少し面倒でした。コードをCruiseControl.NETに移動することも楽しみではありませんでしたが、それも簡単です。
DilbertDave

10
ちなみに、SlowCheetahは素晴らしい拡張機能でしたが、VS 2014以降はサポートされなくなります。著者によると、Sayed Ibrahim Hashimisedodream.com / 2014/08/11 /…です。
bdeem

5
@andrewb、私はここでそれを読みました。しかし、それは一年前でした。スレッドを再訪してコメントを読んだところ、誰かがVS2015 動作するバージョンをここに提供したようです
Anil Natha、2016

2
Visual Studio 2017およびVisual STudio 2019と完全に連携する
ギル

1
それが今ここにあります
Hugo Freitas

573

私はいくつかの解決策を試しましたが、ここで私が個人的に見つけた最も簡単な方法を紹介します。
Danはコメントの中で、元の投稿Oleg Sychのものであると指摘しました— ありがとう、Oleg!

手順は次のとおりです。

1.各構成のXMLファイルをプロジェクトに追加します。

通常Debug、とのRelease構成があるので、ファイルApp.Debug.configとに名前を付けますApp.Release.config。私のプロジェクトでは、環境の種類ごとに構成を作成したので、それを試すことができます。

2.プロジェクトをアンロードし、編集するために.csprojファイルを開きます

Visual Studioでは、エディターで.csprojファイルを編集できます。最初にプロジェクトをアンロードするだけです。次に、それを右クリックし、[ <ProjectName> .csprojの編集 ]を選択します。

3. App。*。configファイルをメインApp.configにバインドします

すべてApp.configApp.*.config参照を含むプロジェクトファイルセクションを見つけます。ビルドアクションが次のように設定されていることがわかりますNone

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

まず、すべてのビルドアクションをに設定しContentます。
次に、すべての構成固有のファイルをメインに依存App.configするようにして、Visual Studioがデザイナーや分離コードファイルのようにそれらをグループ化するようにします。

上記のXMLを以下の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.変換マジックをアクティブにするVS2017より前のVisual Studioバージョンでのみ必要)

ファイルの終わりに

<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変換を楽しむことができます!

ご参考までに

App.*.configファイルが次のように正しく設定されていることを確認してください:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
     <!--magic transformations here-->
</configuration>

4
これをたくさんありがとう!1つの注意点として、csprojを編集した後にプロジェクトに新しい.configファイルを追加すると、それらはApp.configの下にグループ化されて表示されます。私はcsprojを編集する前に1つ追加し、基本的には2つのリンク、1つはグループ化、もう1つはソロになりました。
Jeff Swensen、2011年

8
このアプローチの1つの問題は、プロジェクトのプロパティの[発行]タブを確認し、[アプリケーションファイル]ボタンをクリックすると、app.config、app.Debug.config、 app.Release.configは、発行プロセスの一部として展開する必要があります。確かに、正しいMyApp.exe.configファイルも取得できますが、追加の手荷物を配備したくありません。プロジェクトのapp。*。configファイルを<Content>ではなく<None>として保持する方法が必要です。
Lee Grissom

6
これが除外している問題の1つは、元々Oleg Sychから取った答えが重要な部分を除外していることです。個々のapp。(env).configsにある場合、 '<configuration xmlns:xdt = " schemas.microsoft.com/XML-Document-Transform ">'や<appSettings xdt:Transform = "Replace">のようなものは記載しないでください。または設定行で同様のことを行う属性は機能しません。この最後の情報が重要です。一度追加すると、すべてが機能し始めました。
djangojazz 2015年

24
で置き換えv10.0v$(VisualStudioVersion)、プロジェクトがそれ以降のすべてのバージョンのVSで動作することを確認できます。
Thibault D.

14
エラーが発生しましたMSBuildエラーMSB3021:ファイルをコピーできません。ビルド中にファイル 'obj \ Release \ ConsoleApp.exe'が見つかりませんでした。そこで、ソリューションに新しいLikeを作成するのではなく、ターゲットの<Target Name = "AfterBuild">セクションを再利用するようにソリューションを少し変更します
asidis

137

私が見つけた別の解決策は、変換を使用せず、app.Release.configなどの個別の構成ファイルを用意することです。次に、この行をcsprojファイルに追加します。

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

これにより、正しいmyprogram.exe.configファイルが生成されるだけでなく、Visual Studioのセットアップとデプロイメントプロジェクトを使用してMSIを生成している場合、パッケージ化時にデプロイメントプロジェクトが正しい構成ファイルを使用するようになります。


6
MSBuildの驚異的な驚異。今、私は他に何が可能か疑問に思います。ところで これは、VSから直接クリックオンスを展開する場合にも機能します(投票数が多い回答とは対照的)。
ボリスB.

4
構成にすべてのビルドで同じエントリが多数含まれていると、変更が面倒でエラーが発生しやすくなります。ある環境の.configが変更を見逃していて、もちろんそれが本番であったという問題に対処する。
ジープラン2015

1
設定ファイルの2つのコピーがあることは、開発者が手動でそれを維持している開発者でない限り、問題ではありません。
2015

1
これは美しく、魅力のように機能します!構成の<AppConfig>App.Release.config</AppConfig>既存の<PropertyGroup条件の内側の行だけを貼り付けたところ、ReleaseIDEは<AppConfig>...行の下に波線が表示され、スキーマなどに含まれていないことを示しましたが、とにかくファイルを保存し、プロジェクトファイルを再ロードしてビルドしました。構成でReleaseそれは働いた!
Shiva、

1
これにより、設定デザイナーの機能が失われます。
オンドレイ・

33

私の経験では、環境固有にする必要があるのは、接続文字列、アプリ設定、および多くの場合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、web)で機能します。


私はあなたが持っているのとまったく同じ設定を持っています。しかし、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="user@email.com" deliveryMethod="Network"> <network .../> </smtp>
jgarza '25

私は上手く理解できていない気がします。私は何も変換しません。この構成では、それだけでファイルをコピーしています...
jeroenh

ああ、コピー部分が見えませんでした。単にコピーするのではなく、設定を変換します。とにかくありがとう。
jgarza 2013年

私はこのソリューションが好きです。1つの小さな提案:上記のコピーの例では、コピーのソース引数とターゲット引数を引用符で囲む必要があります。そうしないと、名前にスペースが含まれるディレクトリの場合、Pre-Buildが失敗します
vandre

32

この質問のOlegや他の人に触発されて、私はソリューションhttps://stackoverflow.com/a/5109530/2286801をさらに一歩進めて、次のことを可能にしました。

  • ClickOnceと連携
  • VS 2010のセットアッププロジェクトと展開プロジェクトで動作します
  • VS2010、2013、2015で動作します(2012はテストしていませんが、動作するはずです)。
  • チームビルドで動作します。(A)Visual StudioまたはB)Microsoft.Web.Publishing.targetsおよびMicrosoft.Web.Publishing.Tasks.dllのいずれかをインストールする必要があります)

このソリューションは、MSBuildプロセスで初めてapp.configが参照される前にapp.config変換を実行することで機能します。複数のプロジェクトでの管理を容易にするために、外部ターゲットファイルを使用します。

手順:

他のソリューションと同様の手順。何が変わらないかを引用し、完全性と比較を容易にするために含めました。

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。*。configファイルをメインApp.configにバインドします

すべてのApp.configおよびApp。*。config参照を含むプロジェクトファイルセクションを見つけて、次のように置き換えます。Contentの代わりにNoneを使用していることに気づくでしょう。

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

できた!


1
VS Community 2015 RCで試してみましたが、持っているapp.Debug.configファイルは無視されます。
Khainestar 2015年

私は1つのWinFormsプロジェクトで受け入れられた回答をうまく使用しましたが、不可解な理由により、受け入れられたansを適用できませんでした。別のWinFormsプロジェクト(すべて同じソリューション内)。@bdeemからのこの回答は私の新しいお気に入りです-MSIプロジェクトと正しく相互運用されているため、どうもありがとうございます!
bkwdesign 2016

これはVS 2015では機能していないようです。VisualStudioVersionを10から12に更新しましたが、サイコロは更新していません。何か案は?
Sinaesthetic

@Sinaesthetic詳細を教えてください。VS 2015 Ultimate、Communityなど。VB.NET、C#、エラーはありますか?
bdeem

VS2015 Enterprise。エラーは一切ありません。何もしません。
Sinaesthetic

27

構成ごとに個別の構成ファイル(app.Debug.config、app.Release.configなど)を使用し、プロジェクトファイルで構成変数を使用できます。

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

これにより、組み込みの構成に応じて、正しいProjectName.exe.configファイルが作成されます。


おかげで、私はあなたが抱えている問題を解決するために正確な例を使用しませんでしたが、あなたの例は私に考えさせられ、コピータスクを使用して別の非常に類似した解決策を導きました。
jpierson

これをVS 2015 Community RCの下で試してビルドしましたが、追加したapp。*。configのコンテンツは無視されます。
Khainestar

14

Webアプリケーションプロジェクト構成変換に組み込まれているようなapp.config変換を自動化するための素晴らしい拡張機能を作成しました

この拡張機能の最大の利点は、すべてのビルドマシンにインストールする必要がないことです。


1
特にSlow Cheetahがメンテナンスモードに入り、将来サポートされなくなる可能性があるため、非常に便利な拡張機能。
dthrasher 2015

そうです、この機能がtransformxml msbuildタスクでサポートされるようになったときは、この問題の解決策として、チーターを遅くする必要はありません。私のチームのSWアーキテクトは、プロジェクトに熱心にスローチーターを導入し、すべての構成のデバッグ、ステージング、リリーストランスフォームを作成しました。そのほとんどはトランスフォーメーションを必要としませんでした。言うまでもなく、彼が去った瞬間、私はスローチーターを引き出しました。今は、web.configで単一のtransformxmlタスクを使用しています。ああ、シンプル。遅いチーターに時間と場所がなかったことは言うまでもありません。
HarryTuttle 2016

5

MarketplaceからVisual Studioに「Configuration Transform Tool」をインストールし、VSを再起動します。app.configのメニュープレビュートランスフォームも表示されます。

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


1
これは完全に機能し、ほとんど労力や思考を必要としません。とても有難い。ありがとう。(「プレビュー変換」は機能しませんが、「追加変換」はVS 2017では問題なく完全に機能します)。また、頻繁に更新されるようです。
adudley 2018

1
ソリューションに感謝します。舞台裏では、手を汚さずにDan Abramovが上で説明したことを正確に実行します
Mohammed Dawood Ansari

これが究極のソリューションです。プレビューは、VS 2019でうまく動作しているようだ
カイルチャンピオン

1
私はそれを愛していますが、csprojを少し編集しないと、app.config以外の他のファイルをサポートしていませんでした。それでもプレビューを見るのは素晴らしいです。
Ian1971

4

したがって、私はやや異なるアプローチをとることになりました。Danのステップ3までを実行しましたが、別のファイルApp.Base.Configを追加しました。このファイルには、生成されたすべてのApp.Configに必要な構成設定が含まれています。次に、BeforeBuildを使用して(TransformXmlにYuriを追加)、現在の構成をBase構成でApp.configに変換します。その後、ビルドプロセスは変換されたApp.configを通常どおり使用します。ただし、不快な点の1つは、刻々と変化する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>

3

現在どこにでも投稿されているように見えるソリューションのほんの少しの改善:

<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
  • つまり、現在のVSバージョンを永久に使用する予定がない限り

少し答えるか、それを説明するための情報源を教えてください。
roydukkey 2013

4
$(VisualStudioVersion)MSBuildを直接使用するときに設定されているようには見えません。
ジェレミー・スミス

これは、stackoverflow.com / a / 5109530/2003763へのコメントである必要があります(同じ情報をコメントとして追加しました)
Thibault D.

2

Vishal Joshiが投稿したものの別の代替案を作成しました。ビルドアクションをコンテンツに変更する必要がなくなり、ClickOnce配置の基本的なサポートも実装しました。私はそれを徹底的にテストしなかったので基本と言いますが、それは典型的なClickOnce配置シナリオで動作するはずです。

このソリューションは、既存のWindowsアプリケーションプロジェクト(* .csproj)にインポートされると、ビルドプロセスを拡張してapp.config変換を検討する単一のMSBuildプロジェクトで構成されます。

Visual Studio App.config XML Transformationで詳細な説明を読むことができ、MSBuildプロジェクトファイルはGitHubからダウンロードできます


1

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オンライン(クラウド)サーバーで機能します。


0

提案されたソリューションは、構成ファイルを含むクラスライブラリが別のプロジェクト(私の場合はAzureワーカープロジェクトライブラリ)から参照されている場合は機能しません。正しい変換ファイルをobjフォルダーからフォルダーにコピーしませんbin\##configuration-name##。最小限の変更で機能させるには、AfterCompileターゲットをBeforeCompile次のように変更する必要があります。

<Target Name="BeforeCompile" Condition="exists('app.$(Configuration).config')">
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.