System.Drawing.Common wird nur für Windows unterstützt

Das System.Drawing.Common-NuGet-Paket ist jetzt eine Windows-spezifische Bibliothek. Das Plattformanalysetool gibt bei der Kompilierung für andere Betriebssysteme als Windows zur Kompilierzeit eine Warnung aus.

Bei anderen Betriebssystemen als Windows wird eine TypeInitializationException-Ausnahme mit PlatformNotSupportedException als innerer Ausnahme ausgelöst, sofern Sie keinen Laufzeitkonfigurations-Schalter festlegen.

Altes Verhalten

Vor .NET 6 hat die Verwendung des System.Drawing.Common-Pakets keine Kompilierzeitwarnungen erzeugt, und es wurden keine Laufzeitausnahmen ausgelöst.

Neues Verhalten

Ab .NET 6 gibt das Plattformanalysetool Warnungen zur Kompilierzeit aus, wenn Code, auf den verwiesen wird, für andere Betriebssysteme als Windows kompiliert wird. Darüber hinaus wird die folgende Laufzeitausnahme ausgelöst, sofern Sie keine Konfigurationsoption festlegen:

System.TypeInitializationException : The type initializer for 'Gdip' threw an exception.
      ---- System.PlatformNotSupportedException : System.Drawing.Common is not supported on non-Windows platforms. See https://aka.ms/systemdrawingnonwindows for more information.
      Stack Trace:
           at System.Drawing.SafeNativeMethods.Gdip.GdipCreateBitmapFromFile(String filename, IntPtr& bitmap)
        /_/src/libraries/System.Drawing.Common/src/System/Drawing/Bitmap.cs(42,0): at System.Drawing.Bitmap..ctor(String filename, Boolean useIcm)
        /_/src/libraries/System.Drawing.Common/src/System/Drawing/Bitmap.cs(25,0): at System.Drawing.Bitmap..ctor(String filename)
        /_/src/libraries/System.Resources.ResourceManager/tests/ResourceManagerTests.cs(270,0): at System.Resources.Tests.ResourceManagerTests.EnglishImageResourceData()+MoveNext()
        /_/src/libraries/System.Linq/src/System/Linq/Select.cs(136,0): at System.Linq.Enumerable.SelectEnumerableIterator`2.MoveNext()
        ----- Inner Stack Trace -----
        /_/src/libraries/System.Drawing.Common/src/System/Drawing/LibraryResolver.cs(31,0): at System.Drawing.LibraryResolver.EnsureRegistered()
        /_/src/libraries/System.Drawing.Common/src/System/Drawing/GdiplusNative.Unix.cs(65,0): at System.Drawing.SafeNativeMethods.Gdip.PlatformInitialize()
        /_/src/libraries/System.Drawing.Common/src/System/Drawing/Gdiplus.cs(27,0): at System.Drawing.SafeNativeMethods.Gdip..cctor()

Eingeführt in Version

.NET 6

Typ des Breaking Changes

Diese Änderung kann sich auf Quellkompatibilität und binäre Kompatibilität auswirken.

Grund für die Änderung

Da System.Drawing.Common als schlanker Wrapper für Windows entwickelt wurde, ist die plattformübergreifende Implementierung suboptimal.

libgdiplus ist der Hauptanbieter der plattformübergreifenden Implementierung von System.Drawing.Common auf nativer Seite. libgdiplus ist effektiv eine Neuimplementierung der Teile von Windows, von denen System.Drawing.Common abhängt. Diese Implementierung macht libgdiplus zu einer nicht trivialen Komponente. Etwa 30.000 Zeilen C-Code wurden größtenteils nicht getestet, und es mangelt erheblich an Funktionalität. libgdiplus verfügt auch über zahlreiche externe Abhängigkeiten für die Bildverarbeitung und das Textrendering, z. B. cairo, pango und andere native Bibliotheken. Diese Abhängigkeiten machen die Wartung und den Versand der Komponente noch schwieriger. Seit der Einführung der plattformübergreifenden Mono-Implementierung haben wir zahlreiche Probleme auf libgdiplus zurückgeführt, die nie behoben wurden. Im Vergleich dazu sind andere externe Abhängigkeiten, die wir übernommen haben, z. B. icu oder openssl, hochwertige Bibliotheken. Es ist nicht sinnvoll, libgdiplus auf den Stand zu bringen, das sein Funktionssatz und die Qualität dem Rest des .NET-Stapels entspricht.

Bei der Analyse von NuGet-Paketen haben wir festgestellt, dass System.Drawing.Common plattformübergreifend hauptsächlich für die Bildbearbeitung verwendet wird, z. B. als QR-Codegeneratoren und zum Textrendering. Wir haben keine hohe Grafiknutzung bemerkt, da unsere plattformübergreifende Grafikunterstützung unvollständig ist. Die Verwendung von System.Drawing.Common, die wir in anderen Umgebungen als Windows sehen, wird in der Regel mit SkiaSharp und ImageSharp gut unterstützt.

System.Drawing.Common wird sich weiterhin nur im Kontext von Windows Forms und GDI+ entwickeln.

Um diese APIs für plattformübergreifende Apps zu verwenden, migrieren Sie zu einer der folgenden Bibliotheken:

Alternativ können Sie die Unterstützung für Nicht-Windows-Plattformen in .NET 6 aktivieren, indem Sie den RuntimekonfigurationsschalterSystem.Drawing.EnableUnixSupport in der Datei runtimeconfig.json auf true festlegen.

runtimeconfig.template.json-Vorlagendatei:

{
   "configProperties": {
      "System.Drawing.EnableUnixSupport": true
   }
}

[appname].runtimeconfig.json-Ausgabendatei:

{
   "runtimeOptions": {
      "configProperties": {
         "System.Drawing.EnableUnixSupport": true
      }
   }
}

Hinweis

  • Dieser Konfigurationsschalter wurde hinzugefügt, um plattformübergreifenden Apps, die stark von diesem Paket abhängig sind, Zeit für die Migration zu moderneren Bibliotheken zu geben. Nicht-Windows-Fehler werden jedoch nicht behoben.
  • Dieser Switch ist nur in .NET 6 verfügbar und wurde in .NET 7 entfernt. Weitere Informationen finden Sie unter System.Drawing.Common-Konfigurationsoption wurde entfernt.

Betroffene APIs

System.Drawing-Namespace:

System.Drawing.Drawing2D-Namespace:

System.Drawing.Imaging-Namespace:

System.Drawing.Printing-Namespace:

System.Drawing.Text-Namespace:

Siehe auch