【问题标题】:Replacing <appname>.exe.config with an AfterBuild doesn't apply to <appname>.vshost.exe.config用 AfterBuild 替换 <appname>.exe.config 不适用于 <appname>.vshost.exe.config
【发布时间】:2015-08-04 17:19:54
【问题描述】:

我们在vbproj 中使用AfterBuild 目标来根据所选配置替换配置文件:

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

例如,假设我们有 3 个配置:调试、测试、发布。 Debug 是本地调试配置。测试是用于用户验收测试的预生产环境。发布是我们的生产环境。

App.config 文件中,我们存储了发布环境的配置。在Debug.config 文件中,我们存储了本地调试需要的配置。在Test.config 文件中,我们存储了用户接受环境的配置。

AfterBuild 目标的目标是在构建/执行时用调试配置 (Debug.config) 或测试配置 (Test.config) 替换发布配置 (App.config)。

当我们发布应用程序(发布,App.config)或构建应用程序并启动bin\&lt;appname&gt;.exe(调试或测试)时,一切都按预期工作。

但是,如果我们从 Visual Studio 启动应用程序,使用 Visual Studio 托管进程,正确的配置将复制到 bin\&lt;appname&gt;.exe.config,但似乎 Visual Studio 没有将正确的配置复制到 bin\&lt;appname&gt;.vshost.exe.config。我们尝试清理解决方案,执行 Rebuild before 调试,在启动前手动删除 bin\&lt;appname&gt;.vshost.exe.config 文件,但似乎托管进程总是从默认的 App.config 文件中复制配置。无论我们尝试从 Debug 配置还是从 Test 配置开始,都会出现同样的问题。

为了增加混乱,我们创建了多个测试项目,使用相同的AfterBuild 目标,其中一些可以正常工作,而另一些则不能。所有项目都使用 .Net Framework 4.5.1,但我们也重现了 .Net 4.5 的问题。这似乎不是由项目类型引起的,因为我们能够使用控制台应用程序和 Windows 窗体应用程序重现该问题。

什么可能导致问题?

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

备注

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

【问题讨论】:

  • 只是一个想法。使用 PreBuild 事件并在 app.config 上复制所需的配置,让 VS 完成其通常的工作?
  • 有兴趣看看是否有人知道如何做到这一点......我们尝试过,但失败了,并求助于手动更改配置文件以在 VS 中运行。
  • 很难理解为什么不添加另一个&lt;Copy&gt; 命令。或者更简单,只需打开托管进程选项。
  • @HansPassant :我很确定配置是在启动时复制的,而不是在构建时复制的。如果我们添加另一个&lt;Copy&gt; 命令,无论如何它都不会在启动时执行。
  • @Steve :我们尝试了您建议的方法,但我们仍然观察到相同的行为。如果我们将配置从 Release 切换到 Debug,App.config 中包含了所选配置(Debug)的正确参数,但是宿主进程仍然使用之前的配置(Release)...

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


【解决方案1】:

按照史蒂夫的建议,我们将逻辑移至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>

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

添加以下&lt;Copy&gt; 命令,我们实现了预期的行为:

<!--
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 文件替换为正确的文件。生成的&lt;appname&gt;.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 文件:

【讨论】:

  • 感谢DependentUpon 的那个我不会想到这个。
  • 遇到同样的问题,你是在哪里添加复制命令的?在 ?
【解决方案2】:

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

去掉复选标记:

Project -> Preferences -> Debug -> Enable Visual Studio hosting process

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-16
    • 1970-01-01
    • 2021-06-01
    • 2021-03-05
    • 2014-04-17
    • 1970-01-01
    • 2021-02-03
    • 2015-08-07
    相关资源
    最近更新 更多