App.Config Transformation dla projektów, które nie są projektami sieciowymi w Visual Studio?

546

W przypadku aplikacji sieci Web Visual Studio 2010 mamy funkcje Transformacji konfiguracji, dzięki którym możemy utrzymywać wiele plików konfiguracyjnych dla różnych środowisk. Ale ta sama funkcja nie jest dostępna dla plików App.Config dla usług Windows / WinForms lub aplikacji konsolowej.

Dostępne jest obejście, jak sugerowano tutaj: Zastosowanie magii XDT do App.Config .

Nie jest to jednak proste i wymaga szeregu kroków. Czy istnieje łatwiejszy sposób na osiągnięcie tego samego w przypadku plików app.config?

Amitabh
źródło
Natknąłem się na następujący artykuł, który wygląda nieco prościej, ale sam go nie wypróbowałem. fknut.blogspot.com/2009/11/... Ponadto istnieje prośba o dodanie funkcji do MS Connect, która może być warta głosowania, więc zostanie ona uwzględniona na całym forum w następnej wersji SP lub wersji. connect.microsoft.com/VisualStudio/feedback/details/564414
Kim R

Odpowiedzi:

413

Działa to teraz z dodatkiem Visual Studio AddIn opisanym w tym artykule: SlowCheetah - Web.config Składnia transformacji uogólniona dla dowolnego pliku konfiguracyjnego XML .

Możesz kliknąć prawym przyciskiem myszy plik web.config i kliknąć „Dodaj transformacje konfiguracji”. Gdy to zrobisz, otrzymasz web.debug.config i web.release.config. Jeśli chcesz, możesz utworzyć plik web.whokolwiek.config, o ile nazwa jest zgodna z profilem konfiguracji. Te pliki to tylko zmiany, które chcesz wprowadzić, a nie pełna kopia pliku web.config.

Możesz pomyśleć, że chcesz użyć XSLT do przekształcenia pliku web.config, ale choć intuicyjnie mają rację, w rzeczywistości jest bardzo gadatliwy.

Oto dwie transformacje, jedna przy użyciu XSLT i ta sama przy użyciu składni / przestrzeni nazw XML Document Transform. Podobnie jak w przypadku wszystkich rzeczy w XSLT jest wiele sposobów na zrobienie tego, ale masz ogólny pomysł. XSLT jest uogólnionym językiem transformacji drzewa, podczas gdy to wdrożenie jest zoptymalizowane pod kątem określonego podzestawu typowych scenariuszy. Ale fajne jest to, że każda transformacja XDT jest wtyczką .NET, więc możesz stworzyć własną.

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

Lub to samo poprzez transformację wdrażania:

<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
źródło
Och, to słodkie! Mam aplikację z licznymi plikami konfiguracyjnymi (log4net, nHibernate, web.config) i pamiętanie o ich zmianie było trochę uciążliwe. Nie spodziewałem się również przeniesienia kodu do CruiseControl.NET, ale wygląda na to, że to także pestka.
DilbertDave
10
Do twojej wiadomości, SlowCheetah było fantastycznym rozszerzeniem, które nie będzie już obsługiwane po VS 2014. Według autora, Sayed Ibrahim Hashimi, sedodream.com/2014/08/11/… .
bdeem
5
@ andrewb, przeczytałem to tutaj ; było to jednak rok temu. Po przejrzeniu wątku i przeczytaniu komentarzy wygląda na to, że ktoś dostarczył wersję, która działa tutaj z VS2015 .
Anil Natha
2
Doskonale współpracuje z Visual Studio 2017 i Visual STudio 2019
Guilherme de Jesus Santos
1
Jest tu teraz
Hugo Freitas
573

Wypróbowałem kilka rozwiązań i oto najprostsze, jakie osobiście znalazłem.
Dan zauważył w komentarzach, że oryginalny post należy do Olega Sycha - dzięki, Oleg!

Oto instrukcje:

1. Dodaj plik XML dla każdej konfiguracji do projektu.

Zazwyczaj będziesz mieć Debugi Releasekonfiguracje, więc nazwij swoje pliki App.Debug.configi App.Release.config. W moim projekcie stworzyłem konfigurację dla każdego rodzaju środowiska, więc możesz z tym eksperymentować.

2. Zwolnij projekt i otwórz plik .csproj do edycji

Visual Studio umożliwia edytowanie plików .csproj bezpośrednio w edytorze - wystarczy najpierw rozładować projekt. Następnie kliknij go prawym przyciskiem myszy i wybierz opcję Edycja <Nazwa projektu> .csproj .

3. Powiąż pliki aplikacji. *. Config z głównym plikiem App.config

Znajdź sekcję pliku projektu, która zawiera wszystkie App.configi App.*.configodniesienia. Zauważysz, że ich działania kompilacji są ustawione na None:

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

Najpierw ustaw akcję budowania dla wszystkich Content.
Następnie uzależnij wszystkie pliki specyficzne od konfiguracji od głównego, App.configaby program Visual Studio grupował je tak, jak robi to pliki projektanta i kodu.

Zamień XML powyżej na poniższy:

<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. Aktywuj magię transformacji (konieczne tylko dla wersji Visual Studio wcześniejszych niż VS2017 )

Na końcu pliku po

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

i przed finałem

</Project>

wstaw następujący kod 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>

Teraz możesz ponownie załadować projekt, zbudować go i cieszyć się App.configtransformacjami!

Do Twojej wiadomości

Upewnij się, że twoje App.*.configpliki mają odpowiednią konfigurację:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
     <!--magic transformations here-->
</configuration>
Dan Abramov
źródło
4
Wielkie dzięki za to! Jedna uwaga, jeśli dodasz nowe pliki .config do projektu po edycji csproj, pojawią się one zgrupowane pod App.config. Dodałem jeden przed edycją csproj i zasadniczo skończyłem z dwoma linkami do niego, jednym zgrupowanym i jednym solo.
Jeff Swensen
8
Jednym z problemów związanych z tym podejściem jest to, że kiedy spojrzysz na zakładkę „Publikuj” we właściwościach projektu, a następnie klikniesz przycisk „Pliki aplikacji” ... zauważysz, że app.config, app.Debug.config, app.Release.config są zmuszone do wdrożenia w ramach procesu publikowania. Jasne, otrzymujesz również prawidłowy plik MyApp.exe.config, ale nie chcę, aby ten dodatkowy bagaż został wdrożony. Musi istnieć sposób na zachowanie aplikacji. *. Config plików w projekcie jako <Brak> zamiast <Content>.
Lee Grissom,
6
Jedynym problemem, który dla niektórych pomija, jest odpowiedź pierwotnie wzięta od Olega Sycha, pomijając kluczową kwestię. Jeśli w twojej indywidualnej aplikacji. (Env) .configs NIE WYSTAWIAsz '<konfiguracja xmlns: xdt = " schemas.microsoft.com/XML-Document-Transform ">' i coś w rodzaju <appSettings xdt: Transform = „Replace”> lub atrybuty, które robią podobne rzeczy w liniach ustawień, to nie zadziała. Ta ostatnia informacja jest kluczowa i kiedy ją dodałem, wszystko zaczęło działać.
djangojazz
24
Można wymienić v10.0z v$(VisualStudioVersion)aby upewnić się, że projekt działa ze wszystkimi późniejszymi wersjami VS.
Thibault D.
14
Miałem błąd MSBuild błąd MSB3021: Nie można skopiować pliku. Nie można znaleźć pliku „obj \ Release \ ConsoleApp.exe” podczas kompilacji. Zmieniam więc nieco rozwiązanie, aby ponownie wykorzystać docelową sekcję <Nazwa celu = „AfterBuild”> zamiast tworzyć nowy jak w rozwiązaniu
asidis
137

Innym rozwiązaniem, które znalazłem, jest NIE używanie transformacji, ale tylko oddzielny plik konfiguracyjny, np. App.Release.config. Następnie dodaj tę linię do pliku csproj.

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

Spowoduje to nie tylko wygenerowanie właściwego pliku myprogram.exe.config, ale jeśli do generowania MSI używasz Instalatora i projektu wdrażania w programie Visual Studio, wymusi on, aby projekt wdrożenia używał poprawnego pliku konfiguracji podczas pakowania.

Alec
źródło
6
Niezliczone cuda MSBuild. Teraz zastanawiam się, co jeszcze jest możliwe. Btw. działa to również w przypadku wdrożeń clickonce bezpośrednio z VS (w przeciwieństwie do wyżej głosowanych odpowiedzi).
Boris B.,
4
Zmiany mogą stać się uciążliwe i podatne na błędy, jeśli konfiguracje zawierają wiele wpisów, które są takie same dla wszystkich kompilacji. Radzenie sobie z problemem w tej chwili, w którym .config jednego środowiska pominęło zmianę, i oczywiście była to produkcja.
jeepwran
1
Posiadanie dwóch kopii pliku konfiguracyjnego nie stanowi problemu, o ile programiści nie są tymi, którzy ręcznie go obsługują.
anIBMer
1
To jest piękne, działa jak urok! Wkleiłem tylko <AppConfig>App.Release.config</AppConfig>linię wewnątrz istniejącego <PropertyGroupwarunku dla Releasekonfiguracji, a IDE pokazało krętą linię pod linią <AppConfig>..., mówiąc, że nie ma jej w schemacie czy coś, ale mimo to zapisałem plik i ponownie załadowałem plik projektu i zrobiłem kompilację w Releasekonfiguracji i zadziałało!
Shiva
1
Dzięki temu utracisz funkcjonalność projektanta ustawień.
Ondřej
33

Z mojego doświadczenia wynika, że ​​muszę dostosować do środowiska takie jak parametry połączenia, ustawienia i często ustawienia smpt. System konfiguracji pozwala określić te rzeczy w osobnych plikach. Możesz więc użyć tego w app.config / web.config:

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

Zazwyczaj umieszczam te sekcje dotyczące konfiguracji w osobnych plikach, w podfolderze o nazwie ConfigFiles (w zależności od katalogu głównego rozwiązania lub na poziomie projektu). Plik definiuję według konfiguracji, np. Smtp.config.Debug i smtp.config.Release.

Następnie możesz zdefiniować zdarzenie przed kompilacją:

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

W rozwoju zespołu możesz to jeszcze bardziej ulepszyć, włączając do konwencji% COMPUTERNAME% i / lub% USERNAME%.

Oczywiście oznacza to, że pliki docelowe (x.config) NIE powinny być poddawane kontroli źródła (ponieważ są generowane). Nadal powinieneś dodać je do pliku projektu i ustawić właściwość typu wyniku na „kopiuj zawsze” lub „kopiuj, jeśli nowszy”.

Prosty, rozszerzalny i działa dla wszystkich typów projektów Visual Studio (konsola, winforms, wpf, web).

jeroenh
źródło
Mam dokładnie taką samą konfigurację jak ty. Ale mam problemy z transformacją pliku smtp. Czy umiesz podać oryginał i transformację? Są moje: Plik podstawowy: <?xml version="1.0"?> <smtp deliveryMethod="SpecifiedPickupDirectory"> <specifiedPickupDirectory pickupDirectoryLocation="C:\mail"/> <network host="localhost"/> </smtp> Transformacja:<?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
Nie jestem pewien, czy rozumiem. W tej konfiguracji niczego nie przekształcam, po prostu
kopiuję
Nie widziałem części do kopiowania. Przekształcam konfigurację zamiast po prostu ją kopiować. W każdym razie dzięki.
jgarza
Podoba mi się to rozwiązanie. Jedna mała sugestia: W powyższym przykładzie kopiowania argumenty źródłowe i docelowe kopii powinny być otoczone cudzysłowami; w przeciwnym razie Pre-Build nie powiedzie się w przypadku katalogów ze spacją w nazwie
vandre
32

Zainspirowany przez Olega i innych w tym pytaniu, podjąłem rozwiązanie https://stackoverflow.com/a/5109530/2286801 o krok dalej, aby umożliwić następujące.

  • Działa z ClickOnce
  • Współpracuje z projektami instalacji i wdrażania w VS 2010
  • Działa z VS2010, 2013, 2015 (nie testowałem 2012, chociaż powinien również działać).
  • Działa z Team Build. (Musisz zainstalować A) Visual Studio lub B) Microsoft.Web.Publishing.targets i Microsoft.Web.Publishing.Tasks.dll)

To rozwiązanie działa, wykonując transformację app.config przed odwołaniem do app.config po raz pierwszy w procesie MSBuild. Wykorzystuje zewnętrzny plik celów do łatwiejszego zarządzania wieloma projektami.

Instrukcje:

Podobne kroki do drugiego rozwiązania. Przytoczyłem to, co pozostaje niezmienne, i załączyłem to dla kompletności i łatwiejszego porównania.

0. Dodaj nowy plik do projektu o nazwie 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. Dodaj plik XML dla każdej konfiguracji do projektu.

Zazwyczaj będziesz mieć konfiguracje debugowania i wydania, więc nazwij swoje pliki App.Debug.config i App.Release.config. W moim projekcie stworzyłem konfigurację dla każdego rodzaju środowiska, więc możesz z tym eksperymentować.

2. Zwolnij projekt i otwórz plik .csproj do edycji

Visual Studio pozwala edytować .csproj bezpośrednio w edytorze - wystarczy najpierw rozładować projekt. Następnie kliknij go prawym przyciskiem myszy i wybierz Edytuj .csproj.

3. Powiąż pliki aplikacji. *. Config z głównym plikiem App.config

Znajdź sekcję pliku projektu zawierającą wszystkie odwołania do App.config i App. *. Config i zamień w następujący sposób. Zauważysz, że używamy None zamiast Treści.

<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. Aktywuj magię transformacji

Na końcu pliku po

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

i przed finałem

</Project>

wstaw następujący kod XML:

<Import Project="AppConfigTransformation.targets" />

Gotowy!

zbawić
źródło
1
Próbowałem w VS Community 2015 RC i ignoruje plik app.Debug.config, który mam.
Khainestar
Z powodzeniem wykorzystałem zaakceptowaną odpowiedź w jednym projekcie WinForms .. ale z jakiegoś dziwnego powodu nie mogłem zastosować zaakceptowanej odpowiedzi. do innego projektu WinForms (wszystkie w tym samym rozwiązaniu). Ta odpowiedź od @bdeem to moja nowa ulubiona - ponieważ poprawnie współpracowała z moim projektem MSI - wielkie dzięki!
bkwdesign
To nie działało w VS 2015. Zaktualizowałem VisualStudioVersion z 10 do 12, ale nie ma kości. Jakieś pomysły?
Sinaesthetic
@Sinaesthetic Czy możesz podać nam więcej szczegółów? VS 2015 Ultimate, Społeczność itp. VB.NET, C #, Jakieś błędy?
zbawić
VS2015 Enterprise. Żadnych błędów. Po prostu nic nie robi.
Sinaesthetic
27

Możesz użyć oddzielnego pliku konfiguracyjnego dla każdej konfiguracji, np. App.Debug.config, app.Release.config, a następnie użyć zmiennej konfiguracyjnej w pliku projektu:

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

Spowoduje to utworzenie poprawnego pliku ProjectName.exe.config w zależności od konfiguracji, w której budujesz.

Tevin
źródło
Dzięki, nie użyłem twojego dokładnego przykładu, aby rozwiązać problem, który miałem, ale twój przykład zmusił mnie do myślenia i doprowadził mnie do kolejnej bardzo podobnej duszy za pomocą zadania kopiowania.
jpierson
Wypróbowałem to pod VS 2015 Community RC i buduje, ale następnie ignoruje zawartość aplikacji. *. Config, którą dodałem.
Khainestar
14

Napisałem ładne rozszerzenie do automatyzacji transformacji app.config, takie jak wbudowane w Web Application Project Configuration Transform

Największą zaletą tego rozszerzenia jest to, że nie trzeba go instalować na wszystkich komputerach

Golan Avraham
źródło
1
Bardzo przydatne rozszerzenie, szczególnie teraz, gdy Slow Cheetah wchodzi w tryb konserwacji i może nie być obsługiwany w przyszłości.
dthrasher
Tak, ludzie powinni przestać spowalniać geparda jako rozwiązanie tego problemu, gdy ta funkcja jest teraz obsługiwana przez zadanie msbuild transformxml. Architekt SW z mojego zespołu wprowadził powolny gepard w nadgorliwy sposób do naszego projektu i stworzył transformacje debugowania, tworzenia scen i wydań wszystkich naszych konfiguracji, z których większość nie wymagała transformacji. Nie trzeba dodawać, że w chwili, gdy odszedł, wyciągnąłem geparda, a teraz używamy tylko jednego zadania transformxml na web.config. Ahhhhh, prostota. Nie mówiąc już o tym, że wolny gepard nie miał czasu i miejsca.
HarryTuttle
5

Zainstaluj „Narzędzie do transformacji konfiguracji” w Visual Studio z Marketplace i zrestartuj VS. Zobaczysz także transformację podglądu menu dla app.config.

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

Agnel Amodia
źródło
1
Działa to doskonale i wymaga bardzo małego wysiłku lub myślenia. Bardzo mile widziane. dzięki. („podgląd transformacji” nie działa, ale „dodawanie transformacji” działa idealnie bez problemu na VS 2017). Wydaje się również, że często otrzymuje aktualizacje.
adudley,
1
dziękuję bardzo za rozwiązanie, za kulisami robi dokładnie to, co wyjaśnił Dan Abramov, nie brudząc sobie dłoni
Mohammed Dawood Ansari,
To jest najlepsze rozwiązanie. Podgląd wydaje się działać dobrze z VS 2019.
Kyle Champion
1
Uwielbiam to, ale stwierdziłem, że nie obsługuje innych plików innych niż app.config bez pewnej edycji csproj. Nadal jednak świetnie jest zobaczyć podgląd.
Ian1971
4

Skończyłem więc z nieco innym podejściem. Postępowałem zgodnie z krokami Dana przez krok 3, ale dodałem inny plik: App.Base.Config. Ten plik zawiera ustawienia konfiguracji, które chcesz w każdej wygenerowanej aplikacji. Konfiguracji. Następnie używam BeforeBuild (z dodatkiem Yuri do TransformXml), aby przekształcić bieżącą konfigurację z konfiguracją Base w App.config. Proces kompilacji używa następnie przekształconego pliku App.config w normalny sposób. Jednak jedną z irytacji jest to, że chcesz w jakiś sposób wykluczyć ciągle zmieniający się plik App.config z kontroli źródła, ale inne pliki konfiguracyjne są teraz od niego zależne.

  <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
źródło
3

Tylko mała poprawka do rozwiązania, które wydaje się być teraz wszędzie wszędzie:

<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
  • to znaczy, chyba że planujesz pozostać przy obecnej wersji VS na zawsze
Jurij Makassiouk
źródło
Czy możesz wyjaśnić trochę odpowiedzi lub podać źródła, aby to wyjaśnić?
roydukkey
4
Nie wygląda na $(VisualStudioVersion)to, że jest ustawione, gdy używasz MSBuild bezpośrednio.
Jeremy Smith
To powinien być komentarz do stackoverflow.com/a/5109530/2003763 (właśnie dodałem tam te same informacje jako komentarz)
Thibault D.
2

Stworzyłem inną alternatywę dla tej opublikowanej przez Vishala Joshi, w której usunięto wymóg zmiany działania kompilacji na Treść, a także zaimplementowałem podstawową obsługę wdrażania ClickOnce. Mówię podstawowy, ponieważ nie przetestowałem go dokładnie, ale powinien działać w typowym scenariuszu wdrażania ClickOnce.

Rozwiązanie składa się z pojedynczego projektu MSBuild, który po zaimportowaniu do istniejącego projektu aplikacji systemu Windows (* .csproj) rozszerza proces kompilacji o transformację app.config.

Bardziej szczegółowe objaśnienie można przeczytać na stronie Visual Studio App.config XML Transformation i plik projektu MSBuild może być pobrać z GitHub .

João Angelo
źródło
1

Jeśli korzystasz z TFS online (wersja w chmurze) i chcesz przekształcić App.Config w projekcie, możesz wykonać następujące czynności bez instalowania dodatkowych narzędzi. Od VS => Zwolnij projekt => Edytuj plik projektu => Idź na dół pliku i dodaj:

<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 działa na użytek lokalny i serwer TFS online (Cloud).

Benzoes
źródło
0

proponowane rozwiązanie nie będzie działać, gdy do biblioteki klas z plikiem konfiguracyjnym zostanie odwołany inny projekt (w moim przypadku była to biblioteka projektów roboczych Azure). Nie skopiuje poprawnego transformowanego pliku z objfolderu do bin\##configuration-name##folderu. Aby działało z minimalnymi zmianami, musisz zmienić AfterCompilecel na BeforeCompile:

<Target Name="BeforeCompile" Condition="exists('app.$(Configuration).config')">
avs099
źródło