System.Drawing.Common uniquement pris en charge sur Windows

Le package NuGet System.Drawing.Common est désormais attribué en tant que bibliothèque spécifique à Windows. L’analyseur de plateforme émet un avertissement au moment de la compilation lors de la compilation pour les systèmes d’exploitation non Windows.

Sur les systèmes d’exploitation non Windows, sauf si vous définissez un commutateur de configuration du runtime, une exception TypeInitializationException est levée avec PlatformNotSupportedException comme exception interne.

Ancien comportement

Avant .NET 6, l’utilisation du package System.Drawing.Common ne produisait aucun avertissement au moment de la compilation et aucune exception d’exécution n’était levée.

Nouveau comportement

À compter de .NET 6, l’analyseur de plateforme émet des avertissements au moment de la compilation lorsque le code de référence est compilé pour les systèmes d’exploitation non Windows. En outre, l’exception à l'exécution suivante est levée, sauf si vous définissez une option de configuration :

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

Version introduite

.NET 6

Type de changement cassant

Cette modification peut affecter la compatibilité des sources et la compatibilité binaire.

Raison du changement

Étant donné que System.Drawing.Common a été conçu pour être un wrapper fin sur les technologies Windows, son implémentation multiplateforme est inférieure.

libgdiplus est le principal fournisseur de l’implémentation multiplateforme de System.Drawing.Common du côté natif. libgdiplus est en fait une réimplémentation des parties de Windows dont System.Drawing.Common dépend. Cette implémentation fait de libgdiplus un composant non trivial. Il s’agit d’environ 30 000 lignes de code C qui n’est en grande partie pas testé et il manque beaucoup de fonctionnalités. libgdiplus a également de nombreuses dépendances externes pour le traitement d’images et le rendu du texte, telles que cairo, pango et d’autres bibliothèques natives. Ces dépendances rendent la maintenance et l’expédition du composant encore plus difficile. Depuis l’inclusion de l’implémentation multiplateforme Mono, nous avons redirigé de nombreux problèmes vers libgdiplus qui n’ont jamais été résolus. En comparaison, les autres dépendances externes que nous avons prises, telles que icu ou openssl, sont des bibliothèques de haute qualité. Il n’est pas viable d’atteindre libgdiplus au point où son ensemble de fonctionnalités et sa qualité sont identiques au reste de la pile .NET.

À partir de l’analyse des packages NuGet, nous avons observé que System.Drawing.Common est utilisé principalement pour la manipulation d’images, comme les générateurs de code QR et le rendu de texte. Nous n’avons pas remarqué d’utilisation intensive des graphiques, car le support des graphiques multiplateformes est incomplèt. Les utilisations que nous constatons de System.Drawing.Common dans des environnements non-Windows sont généralement bien prises en charge avec SkiaSharp et ImageSharp.

System.Drawing.Common continuera d’évoluer uniquement dans le contexte de Windows Forms et GDI+.

Pour utiliser ces API pour les applications multiplateformes, migrez vers l’une des bibliothèques suivantes :

Vous pouvez également activer la prise en charge des plateformes non Windows dans .NET 6 en définissant le System.Drawing.EnableUnixSupportcommutateur de configuration du runtime sur true dans le fichier runtimeconfig.json.

Fichier modèle runtimeconfig.template.json :

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

Fichier de sortie [appname].runtimeconfig.json :

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

Notes

  • Cette configuration a été ajoutée pour permettre aux applications multiplateformes qui dépendent fortement de ce package de migrer vers des bibliothèques plus modernes. Toutefois, les bogues non-Windows ne seront pas corrigés.
  • Ce commutateur est disponible uniquement dans .NET 6 et a été supprimé de .NET 7. Pour plus d’informations, consultez Commutateur de configuration System.Drawing.Common supprimé.

API affectées

Espace de noms System.Drawing :

Espace de noms System.Drawing.Drawing2D :

Espace de noms System.Drawing.Imaging :

Espace de noms System.Drawing.Printing :

Espace de noms System.Drawing.Text :

Voir aussi