App.Config Transformation für Projekte, die keine Webprojekte in Visual Studio sind?

546

Für die webbasierte Anwendung von Visual Studio 2010 verfügen wir über Konfigurationsumwandlungsfunktionen, mit denen wir mehrere Konfigurationsdateien für verschiedene Umgebungen verwalten können. Die gleiche Funktion ist jedoch nicht für App.Config-Dateien für Windows Services / WinForms oder Console Application verfügbar.

Wie hier vorgeschlagen, steht eine Problemumgehung zur Verfügung: Anwenden von XDT-Magie auf App.Config .

Es ist jedoch nicht einfach und erfordert eine Reihe von Schritten. Gibt es eine einfachere Möglichkeit, dasselbe für app.config-Dateien zu erreichen?

Amitabh
quelle
Ich bin auf den folgenden Artikel gestoßen, der etwas einfacher aussieht, aber ich habe ihn selbst nicht ausprobiert. fknut.blogspot.com/2009/11/… Außerdem gibt es eine Funktionsanforderung für MS Connect, die es wert sein könnte, abgestimmt zu werden , damit diese in der nächsten SP oder Version allgemein enthalten ist. connect.microsoft.com/VisualStudio/feedback/details/564414
Kim R

Antworten:

413

Dies funktioniert jetzt mit dem in diesem Artikel behandelten Visual Studio AddIn: SlowCheetah - Web.config-Transformationssyntax, die jetzt für jede XML-Konfigurationsdatei verallgemeinert wird .

Sie können mit der rechten Maustaste auf Ihre web.config klicken und auf "Config Transforms hinzufügen" klicken. Wenn Sie dies tun, erhalten Sie eine web.debug.config und eine web.release.config. Sie können eine web.whatever.config erstellen, wenn Sie möchten, solange der Name mit einem Konfigurationsprofil übereinstimmt. Diese Dateien sind nur die Änderungen, die Sie vornehmen möchten, keine vollständige Kopie Ihrer web.config.

Sie könnten denken, Sie möchten XSLT verwenden, um eine web.config zu transformieren, aber obwohl sie sich intuitiv richtig anfühlen, ist sie tatsächlich sehr ausführlich.

Hier sind zwei Transformationen, eine mit XSLT und dieselbe mit der Syntax / dem Namespace der XML-Dokumententransformation. Wie bei allen Dingen gibt es in XSLT mehrere Möglichkeiten, dies zu tun, aber Sie bekommen die allgemeine Vorstellung. XSLT ist eine verallgemeinerte Baumtransformationssprache, während diese Bereitstellungssprache für eine bestimmte Teilmenge gängiger Szenarien optimiert ist. Der coole Teil ist jedoch, dass jede XDT-Transformation ein .NET-Plugin ist, sodass Sie Ihre eigenen erstellen können.

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

Oder dasselbe über die Bereitstellungstransformation:

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
   <appSettings>
      <add name="NewSetting" value="New Setting Value" xdt:Transform="Insert"/>
   </appSettings>
</configuration>
Scott Hanselman
quelle
Oh das ist süß! Haben Sie eine App mit zahlreichen Konfigurationsdateien (log4net, nHibernate, web.config) und denken Sie daran, sie alle zu ändern, war ein bisschen mühsam. Ich freute mich auch nicht darauf, den Code in CruiseControl.NET zu verschieben, aber es sieht auch so aus, als wäre das ein Kinderspiel.
DilbertDave
10
Zu Ihrer Information, SlowCheetah war eine fantastische Erweiterung, die nach VS 2014 nicht mehr unterstützt wird. Laut dem Autor Sayed Ibrahim Hashimi, sedodream.com/2014/08/11/… .
Bdeem
5
@andrewb, lese ich , dass hier ; Das war jedoch vor einem Jahr. Nach dem Faden erneuten Besuch, und das Lesen der Kommentare, sieht aus wie jemand hat eine Version zur Verfügung gestellt , die mit VS2015 funktioniert hier .
Anil Natha
2
Perfektes Arbeiten mit Visual Studio 2017 und Visual STudio 2019
Guilherme de Jesus Santos
1
Es ist jetzt hier
Hugo Freitas
573

Ich habe verschiedene Lösungen ausprobiert und hier ist die einfachste, die ich persönlich gefunden habe.
Dan wies in den Kommentaren darauf hin , dass der Original - Beitrag gehört zu Oleg Sych - danke, Oleg!

Hier sind die Anweisungen:

1. Fügen Sie dem Projekt für jede Konfiguration eine XML-Datei hinzu.

In der Regel haben Sie Debugund ReleaseKonfigurationen, benennen Sie also Ihre Dateien App.Debug.configund App.Release.config. In meinem Projekt habe ich eine Konfiguration für jede Art von Umgebung erstellt. Vielleicht möchten Sie damit experimentieren.

2. Entladen Sie das Projekt und öffnen Sie die .csproj-Datei zur Bearbeitung

Mit Visual Studio können Sie .csproj- Dateien direkt im Editor bearbeiten. Sie müssen lediglich das Projekt zuerst entladen. Klicken Sie dann mit der rechten Maustaste darauf und wählen Sie <Projektname> .csproj bearbeiten .

3. Binden Sie App. *. Config-Dateien an die Haupt-App.config

Suchen Sie den Projektdateibereich, der alle App.configund App.*.configReferenzen enthält . Sie werden feststellen, dass ihre Build-Aktionen auf Folgendes eingestellt sind None:

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

Stellen Sie zunächst die Build-Aktion für alle ein Content.
Machen Sie als Nächstes alle konfigurationsspezifischen Dateien von der Hauptdatei abhängig,App.config damit Visual Studio sie wie Designer- und CodeBehind-Dateien gruppiert.

Ersetzen Sie XML oben durch das folgende:

<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. Aktivieren Sie Transformations Magic (nur für Visual Studio-Versionen vor VS2017 erforderlich ).

Am Ende der Datei nach

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

und vor dem Finale

</Project>

Fügen Sie das folgende XML ein:

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

Jetzt können Sie das Projekt neu laden, erstellen und App.configTransformationen genießen !

Zu Ihrer Information

Stellen Sie sicher, dass Ihre App.*.configDateien das richtige Setup haben:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
     <!--magic transformations here-->
</configuration>
Dan Abramov
quelle
4
Vielen Dank dafür! Ein Hinweis: Wenn Sie die neuen .config-Dateien nach dem Bearbeiten des csproj zum Projekt hinzufügen, werden sie unter App.config gruppiert angezeigt. Ich habe vor dem Bearbeiten des csproj einen hinzugefügt und im Wesentlichen zwei Links dazu erhalten, einen gruppierten und einen solo.
Jeff Swensen
8
Ein Problem bei diesem Ansatz besteht darin, dass Sie, wenn Sie in den Projekteigenschaften auf die Registerkarte "Veröffentlichen" schauen und dann auf die Schaltfläche "Anwendungsdateien" klicken, feststellen, dass app.config, app.Debug.config, app.Release.config müssen im Rahmen des Veröffentlichungsprozesses bereitgestellt werden. Sicher, Sie erhalten auch die richtige MyApp.exe.config-Datei, aber ich möchte nicht, dass dieses zusätzliche Gepäck bereitgestellt wird. Es muss eine Möglichkeit geben, die App. *. Config-Dateien im Projekt als <Keine> anstelle von <Inhalt> beizubehalten.
Lee Grissom
6
Das einzige Problem, das dies für einige auslässt, ist die Antwort, die ursprünglich von Oleg Sych stammt und ein Schlüsselstück auslässt. Wenn Sie in Ihrer individuellen App. (Env) .configs NICHT '<configuration xmlns: xdt = " schemas.microsoft.com/XML-Document-Transform ">' und so etwas wie <appSettings xdt: Transform = "Replace"> auflisten oder Attribute, die ähnliche Aktionen in den Einstellungszeilen ausführen, funktionieren nicht. Diese letzte Information ist der Schlüssel und als ich sie hinzugefügt habe, hat alles angefangen zu funktionieren.
Djangojazz
24
Sie könnten ersetzen v10.0mit v$(VisualStudioVersion)sicherstellen , dass Ihr Projekt funktioniert mit allen neueren Versionen von VS.
Thibault D.
14
Ich hatte einen Fehler MSBuild-Fehler MSB3021: Datei kann nicht kopiert werden. Die Datei 'obj \ Release \ ConsoleApp.exe' konnte während des Builds nicht gefunden werden. Also ändere ich die Lösung ein wenig, um den Zielabschnitt <Target Name = "AfterBuild"> wiederzuverwenden, anstatt ein neues Like in der Lösung zu
erstellen
137

Eine andere Lösung, die ich gefunden habe, besteht darin, die Transformationen NICHT zu verwenden, sondern nur eine separate Konfigurationsdatei zu haben, z. B. app.Release.config. Fügen Sie diese Zeile dann Ihrer csproj-Datei hinzu.

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

Dadurch wird nicht nur die richtige Datei myprogram.exe.config generiert. Wenn Sie zum Erstellen von MSI das Setup- und Bereitstellungsprojekt in Visual Studio verwenden, wird das Bereitstellungsprojekt gezwungen, beim Packen die richtige Konfigurationsdatei zu verwenden.

Alec
quelle
6
Die unerzählten Wunder von MSBuild. Jetzt frage ich mich, was sonst noch möglich ist. Übrigens. Dies funktioniert auch für Clickonce-Bereitstellungen direkt von VS (im Gegensatz zu Antworten mit höheren Stimmen).
Boris B.
4
Änderungen können lästig und fehleranfällig werden, wenn die Konfigurationen viele Einträge enthalten, die für alle Builds gleich sind. Wir haben uns gerade mit einem Problem befasst, bei dem die .config einer Umgebung eine Änderung verpasst hat, und natürlich war es die Produktion.
Jeepwran
1
Es ist kein Problem, zwei Kopien der Konfigurationsdatei zu haben, solange Entwickler diese nicht manuell verwalten.
anIBMer
1
Das ist wunderschön, wirkt wie ein Zauber! Ich habe nur die <AppConfig>App.Release.config</AppConfig>Zeile in die vorhandene <PropertyGroupBedingung für die ReleaseKonfiguration eingefügt und die IDE zeigte eine verschnörkelte Zeile unter der <AppConfig>Zeile ... an, die besagt, dass sie nicht im Schema oder so enthalten ist, aber ich habe die Datei trotzdem gespeichert und die Projektdatei neu geladen und einen Build erstellt in Releaseconfig und es hat funktioniert!
Shiva
1
Dadurch verlieren Sie die Funktionalität des Einstellungsdesigners.
Ondřej
33

Nach meiner Erfahrung sind die Dinge, die ich umgebungsspezifisch machen muss, Dinge wie Verbindungszeichenfolgen, Appsettings und oft smpt-Einstellungen. Das Konfigurationssystem ermöglicht es, diese Dinge in separaten Dateien anzugeben. Sie können dies also in Ihrer app.config / web.config verwenden:

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

Normalerweise füge ich diese konfigurationsspezifischen Abschnitte in separaten Dateien in einem Unterordner namens ConfigFiles ab (abhängig vom Lösungsstamm oder auf Projektebene). Ich definiere eine Datei pro Konfiguration, z. B. smtp.config.Debug und smtp.config.Release.

Dann können Sie ein Pre-Build-Ereignis wie folgt definieren:

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

In der Teamentwicklung können Sie dies weiter optimieren, indem Sie% COMPUTERNAME% und / oder% USERNAME% in die Konvention aufnehmen.

Dies bedeutet natürlich, dass die Zieldateien (x.config) NICHT in die Quellcodeverwaltung gestellt werden sollten (da sie generiert werden). Sie sollten sie dennoch zur Projektdatei hinzufügen und ihre Eigenschaft für den Ausgabetyp auf "Immer kopieren" oder "Kopieren, wenn neuer" setzen.

Einfach, erweiterbar und funktioniert für alle Arten von Visual Studio-Projekten (Konsole, Winforms, Wpf, Web).

jeroenh
quelle
Ich habe genau die gleiche Konfiguration wie Sie. Aber ich habe Probleme beim Transformieren der SMTP-Datei. Können Sie das Original und die Transformation einbeziehen? Dies sind meine: Die Basisdatei: <?xml version="1.0"?> <smtp deliveryMethod="SpecifiedPickupDirectory"> <specifiedPickupDirectory pickupDirectoryLocation="C:\mail"/> <network host="localhost"/> </smtp> Die Transformation:<?xml version="1.0"?> <smtp xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform" xdt:Transform="Replace" from="[email protected]" deliveryMethod="Network"> <network .../> </smtp>
Jgarza
Ich bin mir nicht sicher ob ich das verstehe. In dieser Konfiguration transformiere ich nichts, es kopiert nur Dateien ...
jeroenh
Oh, ich habe den Kopierteil nicht gesehen. Ich transformiere die Konfiguration, anstatt sie nur zu kopieren. Danke trotzdem.
Jgarza
Ich mag diese Lösung. Ein kleiner Vorschlag: Im obigen Kopierbeispiel sollten die Quell- und Zielargumente für die Kopie in Anführungszeichen gesetzt werden. Andernfalls
schlägt
32

Inspiriert von Oleg und anderen in dieser Frage ging ich mit der Lösung https://stackoverflow.com/a/5109530/2286801 einen Schritt weiter, um Folgendes zu ermöglichen.

  • Funktioniert mit ClickOnce
  • Funktioniert mit Setup- und Bereitstellungsprojekten in VS 2010
  • Funktioniert mit VS2010, 2013, 2015 (hat 2012 nicht getestet, sollte aber auch funktionieren).
  • Funktioniert mit Team Build. (Sie müssen entweder A) Visual Studio oder B) Microsoft.Web.Publishing.targets und Microsoft.Web.Publishing.Tasks.dll installieren.)

Diese Lösung führt die Umwandlung von app.config durch, bevor im MSBuild-Prozess zum ersten Mal auf app.config verwiesen wird. Es verwendet eine externe Zieldatei für eine einfachere Verwaltung über mehrere Projekte hinweg.

Anleitung:

Ähnliche Schritte zur anderen Lösung. Ich habe zitiert, was gleich bleibt, und es der Vollständigkeit halber und zum leichteren Vergleich aufgenommen.

0. Fügen Sie Ihrem Projekt eine neue Datei mit dem Namen AppConfigTransformation.targets hinzu

<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. Fügen Sie dem Projekt für jede Konfiguration eine XML-Datei hinzu.

In der Regel verfügen Sie über Debug- und Release-Konfigurationen. Benennen Sie daher Ihre Dateien App.Debug.config und App.Release.config. In meinem Projekt habe ich eine Konfiguration für jede Art von Umgebung erstellt, sodass Sie möglicherweise damit experimentieren möchten.

2. Entladen Sie das Projekt und öffnen Sie die .csproj-Datei zur Bearbeitung

Mit Visual Studio können Sie .csproj direkt im Editor bearbeiten. Sie müssen lediglich das Projekt zuerst entladen. Klicken Sie dann mit der rechten Maustaste darauf und wählen Sie .csproj bearbeiten.

3. Binden Sie App. *. Config-Dateien an die Haupt-App.config

Suchen Sie den Abschnitt mit der Projektdatei, der alle Verweise auf App.config und App. *. Config enthält, und ersetzen Sie ihn wie folgt. Sie werden feststellen, dass wir "Keine" anstelle von "Inhalt" verwenden.

<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. Aktivieren Sie die Transformationsmagie

Am Ende der Datei nach

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

und vor dem Finale

</Project>

Fügen Sie das folgende XML ein:

<Import Project="AppConfigTransformation.targets" />

Erledigt!

bdeem
quelle
1
Versucht in VS Community 2015 RC und es ignoriert die app.Debug.config-Datei, die ich habe.
Khainestar
Ich habe die akzeptierte Antwort erfolgreich für ein WinForms-Projekt verwendet. Aus irgendeinem verwirrenden Grund konnte ich die akzeptierte Antwort jedoch nicht anwenden. zu einem anderen WinForms-Projekt (alle in derselben Lösung). Diese Antwort von @bdeem ist mein neuer Favorit - da sie korrekt mit meinem MSI-Projekt zusammenarbeitet - vielen Dank!
bkwdesign
Dies schien in VS 2015 nicht zu funktionieren. Ich habe die VisualStudioVersion von 10 auf 12 aktualisiert, aber keine Würfel. Irgendwelche Ideen?
Sinaesthetic
@Sinaesthetic Kannst du uns mehr Details geben? VS 2015 Ultimate, Community usw. VB.NET, C #, Fehler?
Bdeem
VS2015 Enterprise. Keine Fehler. Es macht einfach nichts.
Sinaesthetic
27

Sie können pro Konfiguration eine separate Konfigurationsdatei verwenden, z. B. app.Debug.config, app.Release.config, und dann die Konfigurationsvariable in Ihrer Projektdatei verwenden:

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

Dadurch wird abhängig von der Konfiguration, in die Sie einbauen, die richtige Datei ProjectName.exe.config erstellt.

Tevin
quelle
Danke, ich habe Ihr genaues Beispiel nicht verwendet, um das Problem zu lösen, das ich hatte, aber Ihr Beispiel hat mich zum Nachdenken gebracht und mich mit der Aufgabe "Kopieren" zu einer anderen sehr ähnlichen Lösung geführt.
Jpierson
Versuchte dies unter VS 2015 Community RC und es wird erstellt, ignoriert dann aber den Inhalt der App. *. Config, die ich hinzugefügt habe.
Khainestar
14

Ich habe eine nette Erweiterung geschrieben, um die Umwandlung von app.config zu automatisieren, wie die in Web Application Project Configuration Transform integrierte

Der größte Vorteil dieser Erweiterung ist, dass Sie sie nicht auf allen Build-Maschinen installieren müssen

Golan Avraham
quelle
1
Sehr nützliche Erweiterung, insbesondere jetzt, da Slow Cheetah in den Wartungsmodus wechselt und möglicherweise in Zukunft nicht mehr unterstützt wird.
Dthrasher
Ja, Leute sollten aufhören, Geparden als Lösung für dieses Problem zu verlangsamen, wenn diese Funktionalität jetzt von der msbuild-Aufgabe transformxml unterstützt wird. Ein sw-Architekt in meinem Team führte Slow Cheetah auf übereifrige Weise in unser Projekt ein und erstellte Debug-, Stage- und Release-Transformationen aller unserer Konfigurationen, von denen die meisten keine Transformation benötigten. Unnötig zu erwähnen, dass ich in dem Moment, als er ging, den langsamen Geparden herausgezogen habe und jetzt nur noch eine einzelne transformxml-Aufgabe in der web.config verwenden. Ahhhhh, Einfachheit. Um nicht zu sagen, dass der langsame Gepard keine Zeit und keinen Ort hatte.
HarryTuttle
5

Installieren Sie "Configuration Transform Tool" in Visual Studio von Marketplace und starten Sie VS neu. Sie können die Menüvorschau-Transformation auch für app.config sehen.

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

Agnel Amodia
quelle
1
Dies funktioniert perfekt und erfordert sehr wenig Aufwand oder Denken. Sehr geschätzt. Vielen Dank. (Die "Vorschau-Transformation" funktioniert nicht, aber die "Transformationen hinzufügen" funktioniert in VS 2017 problemlos.) Scheint auch oft Updates zu bekommen.
Adudley
1
Vielen Dank für die Lösung, hinter den Kulissen macht es genau das, was Dan Abramov oben erklärt hat, ohne sich die Hand schmutzig zu machen
Mohammed Dawood Ansari
Dies ist die ultimative Lösung. Die Vorschau scheint mit VS 2019 gut zu funktionieren.
Kyle Champion
1
Ich liebe es, habe aber festgestellt, dass es andere nicht app.config-Dateien ohne Bearbeitung des csproj nicht unterstützt. Trotzdem großartig, um die Vorschau zu sehen.
Ian1971
4

Also habe ich einen etwas anderen Ansatz gewählt. Ich folgte Dans Schritten durch Schritt 3, fügte aber eine weitere Datei hinzu: App.Base.Config. Diese Datei enthält die gewünschten Konfigurationseinstellungen in jeder generierten App.Config. Dann verwende ich BeforeBuild (mit Yuris Zusatz zu TransformXml), um die aktuelle Konfiguration mit der Basiskonfiguration in die App.config umzuwandeln. Der Erstellungsprozess verwendet dann wie gewohnt die transformierte App.config. Ein Ärger ist jedoch, dass Sie die sich ständig ändernde App.config später von der Quellcodeverwaltung ausschließen möchten, aber die anderen Konfigurationsdateien sind jetzt davon abhängig.

  <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>
Waggles
quelle
3

Nur eine kleine Verbesserung der Lösung, die derzeit überall veröffentlicht zu werden scheint:

<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
  • Das heißt, es sei denn, Sie planen, für immer bei Ihrer aktuellen VS-Version zu bleiben
Yuri Makassiouk
quelle
Können Sie bitte erklären, dass Sie ein wenig antworten, oder Quellen angeben, um dies zu erklären?
Roydukkey
4
Sieht nicht so aus, als wäre $(VisualStudioVersion)es eingestellt, wenn MSBuild direkt verwendet wird.
Jeremy Smith
Dies sollte ein Kommentar zu stackoverflow.com/a/5109530/2003763 sein (ich habe gerade die gleichen Informationen wie ein Kommentar dort hinzugefügt)
Thibault D.
2

Ich habe eine andere Alternative zu der von Vishal Joshi veröffentlichten erstellt, bei der die Anforderung zum Ändern der Build-Aktion in " Inhalt" entfernt und die grundlegende Unterstützung für die ClickOnce-Bereitstellung implementiert wurde. Ich sage einfach, weil ich es nicht gründlich getestet habe, aber es sollte im typischen ClickOnce-Bereitstellungsszenario funktionieren.

Die Lösung besteht aus einem einzelnen MSBuild-Projekt, das nach dem Import in ein vorhandenes Windows-Anwendungsprojekt (* .csproj) den Erstellungsprozess erweitert, um die Umwandlung von app.config in Betracht zu ziehen.

Eine ausführlichere Erklärung finden Sie unter Visual Studio App.config XML Transformation. Die MSBuild-Projektdatei kann von GitHub heruntergeladen werden .

João Angelo
quelle
1

Wenn Sie ein TFS online (Cloud-Version) verwenden und die App.Config in ein Projekt umwandeln möchten, können Sie Folgendes tun, ohne zusätzliche Tools zu installieren. Von VS => Projekt entladen => Projektdatei bearbeiten => Gehen Sie zum Ende der Datei und fügen Sie Folgendes hinzu:

<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 and Destination funktioniert für die lokale Verwendung und den TFS-Online-Server (Cloud).

Benjamin
quelle
0

Die vorgeschlagene Lösung funktioniert nicht, wenn auf eine Klassenbibliothek mit Konfigurationsdatei aus einem anderen Projekt verwiesen wird (in meinem Fall war es die Azure Worker-Projektbibliothek). Die korrekt transformierte Datei wird nicht von objOrdner zu bin\##configuration-name##Ordner kopiert . Damit es mit minimalen Änderungen funktioniert, müssen Sie das AfterCompileZiel ändern in BeforeCompile:

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