demoshop

demo, trying to be the best_

最近有幸在三個不同的專案內都需要寫 Console 來跑一些批次的動作,寫這種東西要把一些主要參數抽到設定檔應該已經是一個眾所皆知的事情,但是在預設的情況下 App.config 無法自動判斷 Debug 或 Release 來切換內容值,再正式機與測試機輪流測試的時候是一件很麻煩的事情,這時候就懷念起 Web.config 可以自動切換的功能,上網查一下果然有不少解法,所以立刻就寫各文章來當筆記囉。

注意事項 Web.config 的自動置換功能可以參考這篇文章【Visual Studio 2010 單鍵發行簡單使用 Web.Release.config

首先就假設各位已經寫好了 Console 程式,直接來下手改吧,先假設 App.config 裡面的值為這樣

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="Mode" value="Debug"/>
  </appSettings>
</configuration>

(主要是確定你真的有建立App.config)


對專案按滑鼠右鍵選擇「卸載專案」

(如果你有裝套件應該可以有 Edit Project File 可以用)


對卸載後的專案按「滑鼠右鍵」,選擇「編輯」


開啟專案檔後先找到最後一個 PropertyGroup 然後在下面貼上

  <PropertyGroup>
    <ProjectConfigFileName>App.config</ProjectConfigFileName>
  </PropertyGroup>

接者往下找,可以看到

  <ItemGroup>
    <None Include="App.config" />
  </ItemGroup>

將它置換為

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

然後再

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

下方增加

  <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets" />
  <Target Name="AfterBuild">
    <TransformXml Source="@(AppConfigWithTargetPath)" Transform="$(ProjectConfigTransformFileName)" Destination="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')" />
  </Target>

這樣專案檔的設定就完成了,下面附上完整的專案檔內容,如果有找不到位置的看這就對了

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{A609B172-39E3-4250-9F26-24CBEF41904B}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>ConsoleApplication1</RootNamespace>
    <AssemblyName>ConsoleApplication1</AssemblyName>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup>
    <ProjectConfigFileName>App.config</ProjectConfigFileName>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
  <ItemGroup>
    <None Include="App.config" />
    <None Include="App.Debug.config">
      <DependentUpon>App.config</DependentUpon>
    </None>
    <None Include="App.Release.config">
      <DependentUpon>App.config</DependentUpon>
    </None>
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets" />
  <Target Name="AfterBuild">
    <TransformXml Source="@(AppConfigWithTargetPath)" Transform="$(ProjectConfigTransformFileName)" Destination="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')" />
  </Target>

  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>

重新載入專案

(過程中的問題都回"是")


現在你可以看到多了兩個 App.config 的檔案,但因為我們沒有實體檔案所以打上了驚嘆號 圖片


請把這兩個檔案利用「新增」的方式加回來


App.Debug.config 和 App.Release.config 內容的檔案就和 Web.config 的置換檔一樣,置換的方式也相同,這裡有各簡單範例

<?xml version="1.0"?>

<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">

  <appSettings>
    <add key="Mode" value="Release" xdt:Transform="Insert"/>
  </appSettings>
  <!--
    In the example below, the "SetAttributes" transform will change the value of 
    "connectionString" to use "ReleaseSQLServer" only when the "Match" locator 
    finds an atrribute "name" that has a value of "MyDB".
    
    <connectionStrings>
      <add name="MyDB" 
        connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True" 
        xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
    </connectionStrings>
  -->
  <system.web>
    <!--
      In the example below, the "Replace" transform will replace the entire 
      <customErrors> section of your web.config file.
      Note that because there is only one customErrors section under the 
      <system.web> node, there is no need to use the "xdt:Locator" attribute.
      
      <customErrors defaultRedirect="GenericError.htm"
        mode="RemoteOnly" xdt:Transform="Replace">
        <error statusCode="500" redirect="InternalError.htm"/>
      </customErrors>
    -->
  </system.web>
</configuration>

將範例貼上 App.Release.config


這是自己加上去的,所以並不支援 VS2012 內建的「預覽和轉換」功能,因此我們就切換成 Release 編譯,編譯完畢後就會看到你的 App.config 檔增加了一條 appSettings

<add key="Mode" value="Release"/>

利用這種方法即使是寫主控台應用程式也可以穩穩的切換設定檔了。

回應討論