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

Time:02-10

I am trying to track down a VS 2019 build issue for a few weeks which drives me crazy. I have a C# project (targeting .Net Framework 4.8) which VS rebuilds regularly even when nothing has changed. The project is not very complex and has no specific dependencies, but a postbuild event which must always be executed. Hence I used the approach described in this answer, which forces msbuild to do the "up-to-date" check instead of the VS IDE. This has worked well for years, but started to make trouble a few weeks ago.

To create a minimal reproducible example:

  • use the VS project wizard to create a trivial "hello world" console app, .Net Fw 4.8, AnyCpu

  • add the following lines to the csproj file:

    <PropertyGroup>
       <RunPostBuildEvent>Always</RunPostBuildEvent>
       <PostBuildEvent>
       </PostBuildEvent>
       <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
    </PropertyGroup>
    
  • change the "Run Post Build" setting in the IDE's project settings to "On Build Success" (or back to "Always", this does not really matter), save the settings

The Postbuild action is intentionally left empty, one can add arbitrary actions here, but even an empty action will produce the issue (however, the issue.

When I choose to rebuild the solution in the IDE (using Ctrl-Shift-B), without touching anything the source code, the executable is recreated. This effect occurs when the time between two consecutive builds is approx. 10 seconds or more, when I rebuild the solution quicker, the exe file stays untouched.

To make the effect more visible, I set "AssemblyVersion("1.0.0.*"), stripped the "AssemblyInformationalVersion" attribute from AssemblyInfo.cs, so the build system assigns a new build number to the exe file with each new creation, which allows to observe the effect in the Windows Explorer more easily (by activating the "File Version" column in the Explorer view).

Note this effect does not seem to occur when I comment out either the post build event, or the DisableFastUpToDateCheck setting.

I observed this with VS 2019 V16.11.9 and V16.11.10 (currently the latest versions in the "2019" product line).

In my real project, this happens for a central DLL inside a solution where more then 70 other projects depend on, including a large C /CLI dll, resulting in a build time of ~2 minutes - every time I only want to start the debugger, since this causes a new build! And yes, I also tried to set the "project build output" settings to "Diagnostic", but could not find anything suspicious in the large amount of messages.

CodePudding user response:

PostBuildEvent is problematic and 'old style' since it doesn't define its inputs and outputs. Because of that msbuild can't calculate whether it caused any files to change and thus forces a rebuild.

By replacing the postbuildevent with a custom target and by correctly specifying the inputs and outputs of the task, MSBuild can check whether any of the inputs have changed and whether the outputs are up to date to properly decide to skip the build altogether.

See:

PostBuildEvent is also no longer supported in new style SDK projects. Visual Studio will now automatically generate a new target when you setup a postkuild event in the UI.

CodePudding user response:

Starting with jesshouwing's answer, and using this information from Microsoft how to extend the VS build process, I implemented this workaround: in the csproj, I added the following section the end:

    <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>

This seems to work well for now without the nasty effects. The only drawback here is that this custom build step does not show up in the Visual Studio project editor, but I can work with that.

  • Related