阻止 VS 2019 在没有更改源的情况下重建解决方案

Preventing VS 2019 from rebuilding a solution though no source has changed

我试图在几周内追踪 VS 2019 构建问题,这让我发疯。我有一个 C# 项目(针对 .Net Framework 4.8),即使没有任何改变,VS 也会定期重建。该项目不是很复杂,也没有特定的依赖关系,但必须始终执行 postbuild 事件。因此我使用了 中描述的方法,它强制 msbuild 进行“最新”检查而不是 VS IDE。这多年来一直运作良好,但几周前开始出现问题。

要创建一个最小的可重现示例:

Post构建动作是故意留空的,可以在这里添加任意动作,但即使是空动作也会产生问题(但是,问题。

当我选择在 IDE 中重建解决方案(使用 Ctrl-Shift-B)时,在不触及任何源代码的情况下,将重新创建可执行文件。当两次连续构建之间的时间约为10 秒或更长时间,当我更快地重建解决方案时,exe 文件保持不变。

为了使效果更明显,我设置了“AssemblyVersion("1.0.0.*"),从 AssemblyInfo.cs 中剥离了“AssemblyInformationalVersion”属性,因此构建系统为每个新创建的 exe 文件,这允许在 Windows 资源管理器中更容易地观察效果(通过激活资源管理器视图中的“文件版本”列)。

请注意,当我注释掉 post 构建事件或 DisableFastUpToDateCheck 设置时,似乎不会出现这种效果。

我用 VS 2019 V16.11.9 和 V16.11.10(目前是“2019”产品线中的最新版本)观察到了这一点。

在我的真实项目中,这种情况发生在一个解决方案中的一个中央 DLL 上,该解决方案依赖于 70 多个其他项目,包括一个大型 C++/CLI dll,导致构建时间约为 2 分钟 - 每次我只想要启动调试器,因为这会导致新构建!是的,我也尝试设置"project build output" settings to "Diagnostic",但在大量消息中找不到任何可疑的东西。

PostBuildEvent 是有问题的,'old style' 因为它没有定义它的输入和输出。因此 msbuild 无法计算它是否导致任何文件更改并因此强制重建。

通过将 postbuildevent 替换为自定义目标并正确指定目标的输入和输出,MSBuild 可以检查是否有任何输入已更改以及输出是否是最新的以正确决定跳过共建。

参见:

新样式 SDK 项目也不再支持 PostBuildEvent。当您在 UI.

中设置构建后事件时,Visual Studio 现在将自动生成一个新目标

, and using this information from Microsoft how to extend the VS build process 开始,我实施了这个解决方法:在 csproj 中,我在末尾添加了以下部分:

    <Target Name="CustomAfterBuild" AfterTargets="Build" 
          Inputs="... input for postbuild step ..." 
          Outputs=" ... output of postbuild step ..">

       <Message Text="... some message here ..." />
       <!-- here are the post build actions -->
    </Target>

这似乎在没有不良影响的情况下运作良好。这里唯一的缺点是这个自定义构建步骤不会显示在 Visual Studio 项目编辑器中,但我可以使用它。