wpf: Certain MSBuild configuration causes _wpftmp build output directories to not be deleted after each build

.NET Core 3.1.201 Windows 10 build 18363

Problem description:

Certain MSBuild configuration causes the compiler to leave behind directories with a _wpftmp suffix after a build completes. The problem seems to be related to custom <BaseOutputPath>s.

Actual behavior:

Temporary output directories are left behind after every build. A new directory is created per build.

Expected behavior:

Temporary output directories are deleted after every build.

Minimal repro:

WpfApp1.zip

image

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 11
  • Comments: 29 (6 by maintainers)

Commits related to this issue

Most upvoted comments

I’m not sure why it should even be “by design” for a build system to repeatedly generate new directories that appear to never be cleaned or wiped…

That’s interesting, thanks. In our case however this does only seems to be impact WindowsDesktop sdk projects.

I’ve modified the solution provided by @nathan-alden-hp to include a wpf .net framework project and .net core console app: repro.zip

These all pick up their output path from the Directory.build.props, but it’s only the sdk style WindowsDesktop project that leaves behind the temporary directories:

image

From what I understand I’m probably falling into scenario b as both the output path and intermediate path are modified based on the $(MSBuildProjectName)

<BaseArtifactsPath>$(MSBuildThisFileDirectory)artifacts\</BaseArtifactsPath><OutputPath>$(BaseArtifactsPath)bin\$(MSBuildProjectName)\</OutputPath> <BaseIntermediateOutputPath>$(BaseArtifactsPath)obj\$(MSBuildProjectName)\</BaseIntermediateOutputPath>

NB: I only see these extra directories left over in the bin directory, the obj directory is behaving as expected.

This does feel like a bug (or at least undesirable behaviour) and only started happening once we migrated our WPF apps to SDK style projects.

That said, I can work around it easily enough, by adding a post build step in Directory.build.targets to delete the directories:

<Target Name="RemoveWpfTemp" AfterTargets="Build"> <ItemGroup> <WpfTempDirectories Include="$([System.IO.Directory]::GetDirectories(&quot;$(BaseArtifactsPath)bin&quot;,&quot;$(MSBuildProjectName)_*_wpftmp&quot;))"/> </ItemGroup> <RemoveDir Directories="@(WpfTempDirectories)" /> </Target>

This is not a bug; By Design AFAICT.

Deleting build artifacts generated by the temp projects had never been a goal.

The only goal has been deleting the *wpftmp.csproj itself, because it is created alongside the original project inside the cone of the sources directory.

Depending on various build configuration choices, the output directories can be named after either (a) the target assembly or (b) the project name (or something else, which is uncommon).

When (a) is in effect, the *wpftmp.csproj project will simply happen to use the same folders under $(Obj) and $(Bin) as the original project - they happen to share the same target assembly name by design.

When (b) is in effect, msbuild will provision *wpftmp.csproj with its own folders under $(Obj) and $(Bin) based on the project name.

This works the same in .NET Framework and .NET Core; in SDK style projects and in older style projects.

Obviously the problem still isn’t solved. Within 7 days my directory for one wpf library is polluted with 186 wpftmp folder. Is there any progress now?

image

I confirm that this bug also affects non-SDK .NET Framework projects, as suggested by the last paragraph of vatsan-madhavan’s comment from Jul 3, 2020.

I disagree with the assessment that it is not a bug. Even if the implementation is operating as designed, that merely shifts the root cause of the bug from the implementation to the design. This arguably makes it more a severe bug since it could have been caught earlier in the production pipeline and was not.

@lindexi: We are using VS 2022 17.2.5 and just noticed that our project folders are also polluted by random _wpftmp project files. Unfortunately all these files are also published to Github.

OutputPath is never used, it uses IntermediateOutputPath to get the path of the assembly to build in GenerateTemporaryTargetAssembly. The folder created at OutputPath is created by PrepareForBuild but from what I can see, it’s never used. This is the same bug as #5711. The problem is that it’s evaluating properties with different values than the main build. We can’t really evaluate every properties before the build in GenerateTemporaryTargetAssembly because it would break other projects that rely on the evaluation of properties inside GenerateTemporaryTargetAssembly . I have a potential fix that I’m experimenting with right now. It’s working but I have to do more tests to make sure that I’m not breaking anything.

I created this post-build target to deal with these folders:

<!--
  Delete temporary compiler output caused by this bug:
  https://github.com/dotnet/wpf/issues/2930
-->
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
  <Exec Command="FOR /D %%G in (&quot;$(BaseOutputBinPath)*_*_wpftmp&quot;) DO RMDIR /S /Q &quot;%%~G&quot;" />
</Target>

This behavior has been driving me nuts as well. This shouldn’t be by-design. No other project type does this.

Any news?

Any news on this?

Any news on this?

Any news on this?