3

So my code which worked fine yesterday, screwed up when I added a .net 5.0 class library project to my solution.

Error CS1069 The type name 'Bitmap' could not be found in the namespace 'System.Drawing'. This type has been forwarded to assembly 'System.Drawing.Common, Version=0.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' Consider adding a reference to that assembly.

There is just one problem, when i look at what replaced "References" it now says "Dependencies" and when I try to add a dependency, "Add reference" is gone and there are no more .net assemblies being shown except under COM projects and type libs and when I add system.drawing etc, the error still remains and the code remains unreadable.

John Sohn
  • 100
  • 1
  • 9
  • Are you using a different/updated version of Visual Studio than yesterday? – gunr2171 Apr 15 '21 at 18:10
  • What framework version are your other projects in the solution targetting? –  Apr 15 '21 at 18:12
  • .net framework 4.8 – John Sohn Apr 15 '21 at 18:12
  • the add option just defaulted to 5.0 – John Sohn Apr 15 '21 at 18:13
  • and yes gnur2171, I applied a .vs 2019 update yesterday to add the .5 framework. mebbe I should just stay back where the code was actually seemingly very stable other than object serialization sucking ? – John Sohn Apr 15 '21 at 18:14
  • 4
    .NET 5 is .NET Core, and **.NET Core is radically different to .NET Framework**. That's why. – Dai Apr 15 '21 at 18:14
  • 2
    @JohnSohn .Net 5 isn't less stable. There are simply *breaking changes* in the upgrade from .Net Framework versions, because .Net 5 is substantially different, in a really good way. –  Apr 15 '21 at 18:16
  • so like a really good thing is altering a basic component of the standard workflow so that things like assemblies are no longer visible ? you did not answer my question, I have no idea who would upvote that comment. and why I'd be downvoted for stating a fact. Microsoft has a long history of dropping bombs on the IT and Developer community like this that are later abandoned. Silverlight. XNA. LightSwitch, Metro. etc etc etc. Why is it an improvement to remove my ability to add an assembly reference containing needed elements of a namespace ? – John Sohn Apr 15 '21 at 18:22
  • and I didn't say it was unstable I said they broke a working product, which in this case is visual studio since following their suggestions is actually impossible through the interface even with a brand new project created specifically in .net 5.0. – John Sohn Apr 15 '21 at 18:23
  • also check the docs. https://learn.microsoft.com/en-us/dotnet/api/system.drawing.bitmap?view=net-5.0 – John Sohn Apr 15 '21 at 18:24
  • You're really making a big deal out of nothing. Don't make the upgrade, if that's your jam. No one is forcing it. But, IMO, the upgrade *is worth it.* –  Apr 15 '21 at 18:44
  • well lets examine that. Why ? – John Sohn Apr 15 '21 at 18:55
  • 1
    I suggest researching it yourself. –  Apr 16 '21 at 01:25

2 Answers2

6

There are multiple reasons for what you're experiencing, I'll try to explain with a variety of assorted (and unordered) bullet-points:

Why isn't System.Drawing in .NET Core?

  • ".NET 5" is the next iteration of .NET Core 3.1, not the .NET Framework 4.8 (.NET 5 comes immediately after .NET Core 3.1, there was never was a ".NET Core 4" to avoid confusion with .NET Framework 4).
  • .NET Core (including .NET 5) is designed to be cross-platform (i.e. to support Windows, Linux, macOS) with a single runtime.
    • Whereas previously people had to target .NET Framework for Windows, and target Mono, Xamarin, Unity, UWP, Silverlight, etc - which made multi-platform development in C# a pain.
    • Note that while Windows, Linux, and macOS now all share the real McCoy .NET 5 (and Silverlight is dead), other platforms like Xamarin, Unity, Mono, and UWP still have their own separate implementations of .NET (CLR+BCL) hence the need for ".NET Standard". At least we don't need those weird "Shared Projects" and "Portable Framework" projects anymore, phew!
  • In the .NET Framework, the System.Drawing API is just a .NET wrapper over Win32's GDI/GDI+, which means it's not cross-platform.
    • While System.Drawing seems like a platform-independent API, if you look closely at public types and methods like Graphics, Brush, Bitmap, Image and so on you'll see that they're all just thin wrappers and leaky-abstractions over GDI+. Mono does have System.Drawing reimplemented for Linux, however they did it by reimplementing GDIPLUS.dll which is about as horrible as it sounds.
  • So because System.Drawing is not cross-platform it was removed from .NET Core's "in-box" API.

So now you're wondering how you can get System.Drawing in .NET Core...

How can I get System.Drawing in .NET Core?

Earlier questions asked on StackOverflow from when .NET Core was more anaemic (and not yet pitched as a replacement for .NET Framework 4) have suggested switching to completely different and incompatible (but cross-platform-by-design) library, such as ImageSharp or ImageProcessor, however a better solution for Windows-only applications exists: the official Microsoft Windows Compatibility Pack (note that the aforementioned blog article is from 2017; as of 2021 the Windows Compatibility Pack is pretty-much fully implemented now).

All you need to do is open the NuGet package manager built-in to Visual Studio and add Microsoft.Windows.Compatibility as a package-reference and magically System.Drawing will be available for use in your application. You can also access the NuGet package manager via the Dependencies context-menu in Solution Explorer.

If you're using the .NET CLI ("command-line interface", not the "common language infrastructure", hurrah for overloaded acronyms) then just run dotnet add package Microsoft.Windows.Compatibility.

But why can't I add assembly references in .NET Core like I used to in .NET Framework?

You can!. It's just that (as of April 2021, running Visual Studio 2019 16.9) the UI for adding an assembly reference is kinda horrible.

  • You can do it manually by editing your .csproj and adding a <Reference Include="pathToDll.dll" /> (in the same <ItemGroup> as the other references).

  • You can do it from within Visual Studio by ignoring the missing menu option and using the Add Project Reference dialog:

    • Follow these steps

      1. Go Solution Explorer > Your Project > Dependencies > Add Project Reference.
        enter image description here
      2. In the popup dialog, choose the Browse tab:
        enter image description here
      3. Then click the Browse... button: enter image description here
      4. Then browse for your target assembly DLL:
      5. Voila - the added assembly reference will appear under a new Assemblies node under Dependencies:
        enter image description here
    • Do note that (generally speaking, there are exceptions) you can only reference assembly DLLs that target .NET Core or .NET Standard. Because most DLLs built for .NET Core and .NET Standard exist as NuGet packages anyway there isn't much need to add an assembly reference directly.

Dai
  • 141,631
  • 28
  • 261
  • 374
  • The GDI classes contain the only image processing code as well, and windows forms should be ported. I think I remember reading that windows forms was supposed to be contained in .net 5.0. There really is no reason they can't backend to GTK or something using the proper classes or implement libpng writers etc. This is one of the things .net is supposed to be about in the first place and this next is opinion I find the gdi classes more useful than say asp.net that os products really work better than. – John Sohn Apr 18 '21 at 03:36
  • 1
    This should be marked as accepted answer! Thank you – Carlos Aug 19 '21 at 07:34
  • @JohnSohn "there really is no reason they can't backend to GTK or something" - no, it is impossible to use GTK as a backend for WinForms because WinForms (and GDI) are far too tightly tied to Windows' `USER32` and Common Controls. I'll admit that the _trivial case_ of a simple UI of buttons in a form can probably be handled, but hardly any application is like that, though. Most of the work wouldn't be about adding features until parity, but would be about replicating all of WinForms' bugs and behavioural quirks. There's no fun in that. If you want xplat WinForms, use WINE, imo. – Dai Sep 07 '21 at 20:37
-4

Microsoft seems to have migrated Add Reference to standard SDK assemblies to "Manage NuGet Packages".. a step I do not understand the point of since the correct assembly is mixed in with third party user contributed search results.

Simply click where references would have been and is now dependencies, and right-click and then click Manage Nuget Packages, do a search for the assembly and VERIFY that Microsoft published it and it meets the .net Core requirements.

Yeah they dropped the ball on this in my humble opinion. Took me a minute to figure out that standard assemblies do not appear to be installed on the system.

The package gets installed under your user account's home directory, not in a system-wide folder requiring elevated user permissions to access the dll, so if your account is bugged, you get to a nice infected copy of the assembly each and every time :)

  • 3
    @JohnSohn: I did not downvote, but I note that the answer is about half editorializing comments on design choices rather than a straightforward answer; that might justify a downvote as it indicates a point at which the answer could be made more useful. Though it is sometimes appropriate to note when a design choice is confusing, and how to resolve that confusion, one risks coming across as ranting. – Eric Lippert Apr 15 '21 at 19:22