对于Visual Studio 2010基于Web的应用程序,我们有配置转换功能,通过它我们可以为不同的环境维护多个配置文件。但同样的功能不适用于Windows服务/WinForms或控制台应用程序的App.Config文件。

这里有一个可用的解决方案:对App.Config应用XDT魔术。

然而,这并不简单,需要一些步骤。是否有更简单的方法来实现同样的app.config文件?


当前回答

我创建了Vishal Joshi发布的另一个替代方案,其中将构建动作更改为内容的需求被删除,并实现了对ClickOnce部署的基本支持。我说基本,是因为我没有彻底测试它,但它应该在典型的ClickOnce部署场景中工作。

该解决方案由一个MSBuild项目组成,一旦导入到现有的windows应用程序项目(*.csproj),将构建过程扩展到考虑app.config转换。

你可以在Visual Studio App.config XML Transformation上阅读更详细的解释,MSBuild项目文件可以从GitHub下载。

其他回答

我发现的另一个解决方案是不使用转换,而只是有一个单独的配置文件,例如app.Release.config。然后将这一行添加到csproj文件中。

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

这不仅会生成正确的myprogram.exe.config文件,而且如果你在Visual Studio中使用安装和部署项目来生成MSI,它会强制部署项目在打包时使用正确的配置文件。

建议的解决方案将不工作时,类库配置文件引用从另一个项目(在我的情况下,它是Azure工作项目库)。它不会将正确转换后的文件从obj文件夹复制到bin\##configuration-name##文件夹。为了使它在最小的变化下工作,你需要将AfterCompile target改为BeforeCompile:

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

根据我的经验,我需要使环境特定的东西是像连接字符串、appsettings和通常的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)。

受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—您只需要首先卸载项目。然后右键单击它并选择Edit .csproj。

3.绑定程序。*。配置文件到主App.config

找到包含所有App.config和App.*的项目文件部分。配置引用和替换如下所示。您将注意到我们使用None而不是Content。

<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. 激活转换魔法 在文件结束后 <进口项目= " $ (MSBuildToolsPath) \ Microsoft.CSharp。目标" / > 在期末考试之前 > < /项目

插入以下XML文件:

<Import Project="AppConfigTransformation.targets" />

完成了!

我创建了Vishal Joshi发布的另一个替代方案,其中将构建动作更改为内容的需求被删除,并实现了对ClickOnce部署的基本支持。我说基本,是因为我没有彻底测试它,但它应该在典型的ClickOnce部署场景中工作。

该解决方案由一个MSBuild项目组成,一旦导入到现有的windows应用程序项目(*.csproj),将构建过程扩展到考虑app.config转换。

你可以在Visual Studio App.config XML Transformation上阅读更详细的解释,MSBuild项目文件可以从GitHub下载。