System.Drawing.Common solo se admite en Windows

El paquete NuGet System.Drawing.Common ahora se asigna como biblioteca específica de Windows. El analizador de la plataforma emite una advertencia en tiempo de compilación al compilar para sistemas operativos distintos de Windows.

En sistemas operativos distintos de Windows, a menos que establezca un modificador de configuración en tiempo de ejecución, se produce una excepción TypeInitializationException con PlatformNotSupportedException como excepción interna.

Comportamiento anterior

Antes de .NET 6, el uso del paquete System.Drawing.Common no generaba ninguna advertencia en tiempo de compilación, y no se producía ninguna excepción en tiempo de ejecución.

Comportamiento nuevo

A partir de .NET 6, el analizador de la plataforma emite advertencias en tiempo de compilación cuando el código de referencia se compila para sistemas operativos distintos de Windows. Además, se produce la siguiente excepción en tiempo de ejecución, a menos que establezca una opción de configuración:

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

Versión introducida

.NET 6

Tipo de cambio importante

Este cambio puede afectar a la compatibilidad de origen y la compatibilidad binaria.

Motivo del cambio

Dado que System.Drawing.Common se diseñó para ser un contenedor fino en tecnologías Windows, su implementación multiplataforma es inferior a lo esperado.

libgdiplus es el proveedor principal de la implementación multiplataforma de System.Drawing.Common en el lado nativo. libgdiplus es realmente una reimplementación de las partes de Windows de las que depende System.Drawing.Common. Esa implementación hace que libgdiplus sea un componente no trivial. Se trata de unas 30 000 líneas de código de C que, en su mayoría, no se ha probado y que carece de muchas funcionalidades. libgdiplus también tiene varias dependencias externas para el procesamiento de imágenes y la representación de texto, como cairo, pango y otras bibliotecas nativas. Esas dependencias hacen que el mantenimiento y el envío del componente sean aún más complicados. Desde la inclusión de la implementación multiplataforma de Mono, hemos redirigido diversos problemas a libgdiplus que nunca se corrigieron. En comparación, otras dependencias externas que hemos tomado, como icu o openssl, son bibliotecas de alta calidad. No es viable hacer que libgdiplus llegue al punto en el que su conjunto de características y su calidad estén a la par del resto de la pila de .NET.

A partir del análisis de paquetes NuGet, hemos observado que System.Drawing.Common se usa principalmente en varias plataformas para la manipulación de imágenes, como generadores de código QR y representación de texto. No hemos observado un uso extendido de gráficos, ya que la compatibilidad con gráficos multiplataforma está incompleta. Los usos que vemos System.Drawing.Common en entornos distintos de Windows suelen ser compatibles con SkiaSharp e ImageSharp.

System.Drawing.Common seguirá evolucionando solo en el contexto de Windows Forms y GDI+.

Para usar estas API para aplicaciones multiplataforma, migre a una de las bibliotecas siguientes:

Como alternativa, puede habilitar la compatibilidad con plataformas que no sean Windows en .NET 6 si establece el modificador de configuración en tiempo de ejecuciónSystem.Drawing.EnableUnixSupport en true en el archivo runtimeconfig.json.

Archivo de plantilla runtimeconfig.template.json:

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

Archivo de salida [appname].runtimeconfig.json:

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

Nota

  • Este modificador de configuración se agregó para dar a las aplicaciones multiplataforma que dependen mayormente de este paquete tiempo para migrar a bibliotecas más modernas. Sin embargo, los errores que no son de Windows no se corregirán.
  • Este modificador solo está disponible en .NET 6 y se quitó en .NET 7. Para obtener más información, consulte Se ha quitado el modificador de configuración System.Drawing.Common.

API afectadas

Espacio de nombres System.Drawing:

Espacio de nombres System.Drawing.Drawing2D:

Espacio de nombres System.Drawing.Imaging:

Espacio de nombres System.Drawing.Printing:

Espacio de nombres System.Drawing.Text:

Vea también