dotnet / project-system

The .NET Project System for Visual Studio
MIT License
968 stars 386 forks source link

Visual Studio overwriting multi-targeted DLLs in bin with wrong target framework on solution load #9352

Closed brettpostin closed 8 months ago

brettpostin commented 9 months ago

Visual Studio Version

17.7.7

Summary

TL;DR Visual Studio is overwriting net48 DLLs in the root web application bin with netstandard2.1 versions, upon solution load.

Explanation

Steps to Reproduce

  1. https://github.com/brettpostin/TargetingIssue I have successfully reproduced the issue in this repository, however it is more sporadic. In our real-world solution, we can reproduce consistently. I'm unsure of the trigger or differences.
  2. Open the solution in Visual Studio
  3. Build the solution and run to test
  4. Close Visual Studio
  5. (optional) Enable a file watcher on the web app bin directory to monitor file changes
  6. Start Visual Studio (Run as Administrator)
  7. Load the solution
  8. (optional) If you have a file watcher, you should see one of the class library files change
  9. Inspect the changed DLL, you will see it is targeting netstandard2.1

If you cannot immediately reproduce, adding a new multi-targeted class library may help.

Expected Behavior

The ASP.NET web app project should only ever pull in the net48 versions of the multi-targeted projects. Visual Studio should not overwrite DLLs on solution load, or at least should resolve the correct target framework.

Actual Behavior

Visual Studio is incorrectly resolving the wrong target framework on solution load, and overwriting the correct DLLs in the web app bin folder.

User Impact

This is causing significant friction to our developers, who are unnecessarily forced to constantly rebuild a large .NET solution.

drewnoakes commented 8 months ago

Hi @brettpostin, thanks for the detailed issue and especially for the repro repo and clear steps.

I've tried your steps several times and haven't been able to reproduce the DLL changing in the output directory. To make sure I'm checking the right thing, I'm looking at TargetingIssue\bin\TargetingIssueCore.dll during solution load and monitoring for any changes. I didn't see any such changes, and confirmed the .NET 4.8 file remains. Also, I wasn't performing any build or run at step 7 — I was just watching the output directory.

The web app here is actually a legacy project which is not a kind of project that the team behind this GitHub repo owns. Could you please copy the above into a new feedback ticket on developer community? If you link it here, I'll make sure it's routed to the correct team and will be able to follow along in case I can help clarify anything during triage.

I'm surprised that VS is copying any files at all during solution load. Perhaps there's something about the legacy project system I don't understand that's causing this.

drewnoakes commented 8 months ago

Looking in TargetingIssueCore.csproj I do see something that's a little worrying:

    <OutputPath>bin\$(Configuration)\</OutputPath>

This implies that all built files should go into a single output directory, as it doesn't mention anything about the target framework in use. I do see net48 and netstandard2.1 folders under bin/Debug though, but I wonder whether the referencing project is getting confused about the binary to reference because of this somehow. Does the problem reproduce if you use the default output paths, without attempting to override anything?

brettpostin commented 8 months ago

Thanks for taking a look @drewnoakes.

Would you mind pointing me in the right direction to the feedback ticket location please? Just so i've got the right place.

We are surprised that VS is doing anything to the \bin folder on solution load too. Which is why we suspect this is some sort of bug. I've tried taking out the <OutputPath> nodes, but VS complains that neither <BaseOutputPath> or <OutputPath> exist in the web project file.

I tried setting the <BaseOutputPath> which does generate a "\bin\Debug" subfolder, but no target framework. I'm unable to actually load the application in this configuration with the error:

Could not load type '[VENDOR].Web.MvcApplication'.

Many suggest changing the output path to \bin, which is what i suspect we did when we originally set this up 10+ years ago!

drewnoakes commented 8 months ago

Thanks for trying that change.

You can send feedback as described in https://learn.microsoft.com/en-us/visualstudio/ide/how-to-report-a-problem-with-visual-studio?view=vs-2022

If you post the link here, I'll make sure it gets sent to the correct team.

brettpostin commented 8 months ago

Thanks @drewnoakes.

Feedback Here

drewnoakes commented 8 months ago

Thank you. I've checked the ticket and will follow it for updates.

peter0302 commented 2 months ago

Same issue here. ASP.NET Core Server + Blazor client application. There's a shared DLL that compiles to both NET8.0 (for Blazor) and NET8.0-windows (for the server).

On first server run (with or without debugger) it's fine. Then on subsequent runs, the DLL is replaced in the server app's bin\net8.0-windows folder with the net8.0 verison of the dependency. I then get a type not found error because the non-Windows DLL is missing dependencies.

Also this is VS17.10 and the issue did not occur in 17.8. This only started after updating. (I did not use 17.9). And all the projects are .NET Core projects, not legacy projects.