用AfterBuild替换<appname> .exe.config不适用于<appname> .vshost.exe.config

时间:2015-05-22 15:42:36

标签: c# .net vb.net visual-studio app-config

我们在AfterBuild中使用vbproj目标替换配置文件,具体取决于所选配置:

<Target Name="AfterBuild" Condition="'$(Configuration)' != 'Release'">
  <Delete Files="$(TargetDir)$(TargetFileName).config" />
  <Copy SourceFiles="$(ProjectDir)$(Configuration).config" DestinationFiles="$(TargetDir)$(TargetFileName).config" />
</Target>

作为一个例子,假设我们有3种配置:Debug,Test,Release。 Debug是本地调试配置。测试是用于用户验收测试的预生产环境。发布是我们的生产环境。

App.config文件中,我们存储Release环境的配置。在Debug.config文件中,我们存储配置以满足本地调试需求。在Test.config文件中,我们存储了用户接受环境的配置。

AfterBuild目标的目标是在使用Debug配置(App.config)或测试配置({{1})构建/执行时替换Release配置(Debug.config) })。

当我们发布应用程序(发布,Test.config)或构建应用程序并启动App.config(调试或测试)时,一切都按预期工作。

但是,如果我们使用Visual Studio托管进程从Visual Studio启动应用程序,则会将正确的配置复制到bin\<appname>.exe,但似乎Visual Studio不会将正确的配置复制到{{1 }}。我们尝试清理解决方案,在调试之前执行Rebuild ,在启动之前手动删除bin\<appname>.exe.config文件,但似乎托管进程始终从默认bin\<appname>.vshost.exe.config复制配置文件。无论我们尝试使用Debug配置还是Test配置,都会出现同样的问题。

为了增加困惑,我们使用相同的bin\<appname>.vshost.exe.config目标创建了多个测试项目,其中一些正常工作,而另一些则没有。所有项目都使用.Net Framework 4.5.1,但我们也使用.Net 4.5重现了这个问题。它似乎不是由项目类型引起的,因为我们能够使用控制台应用程序以及Windows窗体应用程序重现该问题。

可能导致问题的原因是什么?

或者,我们可以使用其他解决方案来管理每个环境的配置吗?

备注

  • 我们使用Release环境的默认App.config文件 因为ClickOnce似乎不支持AfterBuild目标。
  • 我们使用Visual Studio Express 2013 for Windows Desktop,因此我们不能使用像SlowCheetah这样的插件。

2 个答案:

答案 0 :(得分:3)

根据Steve的建议,我们将逻辑移至BeforeCompile目标,指定根据所选配置替换App.config

<Target Name="BeforeCompile">
    <Delete Files="$(ProjectDir)App.config" />
    <Copy SourceFiles="$(ProjectDir)$(Configuration).config" DestinationFiles="$(ProjectDir)App.config" />
      <Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
    </Copy>
</Target>

它不会每次都替换文件,当它发生时,它不一定适用于<appname>.vshost.exe.config文件。我们偶然发现了另一个引导我们走上正确道路的答案:Can Visual Studio automatically adjust the name of other file as it does with app.config?

添加以下<Copy>命令,我们实现了所需的行为:

<!--
Copy the application's .config file, if any.
Not using SkipUnchangedFiles="true" because the application may want to change
the app.config and not have an incremental build replace it.
-->
<Copy
    SourceFiles="@(AppConfigWithTargetPath)"
    DestinationFiles="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')"
    OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
    Retries="$(CopyRetryCount)"
    RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
    UseHardlinksIfPossible="$(CreateHardLinksForAdditionalFilesIfPossible)"
    >

    <Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>

</Copy>

我们现在为每个配置配置了一个配置文件(Debug.configTest.configRelease.config)。 Visual Studio在每次构建/启动时将App.config文件替换为正确的文件。生成的<appname>.vshost.exe.config文件包含正确的参数。

<强>加成

此解决方案的基本优势是每个配置都有一个配置文件,因此我们可以更新.vbproj文件并替换,例如,

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

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

所有配置文件将在Visual Studio中的主App.config文件下分组: enter image description here

答案 1 :(得分:0)

对我来说,它有助于禁用VisualStudio托管过程。

删除以下位置的复选标记:

var p = this.props.navigation.getParam('name'||'No name')

这将阻止Visual Studio覆盖* config文件。