当前位置: 首页 > 工具软件 > common > 使用案例 >

linux docker 中使用 System.Drawing.Common 异常 System.Drawing.Common 仅在 Windows 上受支持

闾丘树
2023-12-01

System.Drawing.Common NuGet 包现在被归类为特定于 Windows 的库。为非 Windows 操作系统编译时,平台分析器会在编译时发出警告。

在非 Windows 操作系统上,除非您设置运行时配置开关,否则将引发TypeInitializationException异常,其中PlatformNotSupportedException作为内部异常。

旧行为

在 .NET 6 之前,使用 System.Drawing.Common 包不会产生任何编译时警告,也不会引发运行时异常。

新行为

从 .NET 6 开始,平台分析器会在为非 Windows 操作系统编译引用代码时发出编译时警告。此外,除非您设置配置选项,否则会引发以下运行时异常:

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

版本介绍

.NET 6

重大变更类型

此更改会影响源代码兼容性二进制兼容性

变化的原因

因为System.Drawing.Common被设计为对 Windows 技术的精简包装,所以它的跨平台实现是次要的。

libgdiplus是原生端跨平台实现的主要提供者System.Drawing.Commonlibgdiplus实际上是对System.Drawing.Common依赖的 Windows 部分的重新实现。该实现是libgdiplus一个重要的组件。大约 30,000 行 C 代码基本上未经测试,并且缺乏很多功能。libgdiplus还具有许多用于图像处理和文本渲染的外部依赖项,例如cairopango和其他本机库。这些依赖关系使维护和运输组件更具挑战性。自从包含 Mono 跨平台实现以来,我们已经将许多问题重定向到libgdiplus从未得到修复的问题。相比之下,我们采用的其他外部依赖项,例如icuopenssl,是高质量的库。libgdiplus使其功能集和质量与 .NET 堆栈的其余部分相提并论是不可行的。

通过对 NuGet 包的分析,我们观察到它System.Drawing.Common主要用于跨平台的图像处理,例如 QR 码生成器和文本渲染。我们没有注意到大量的图形使用,因为我们的跨平台图形支持不完整。SkiaSharp 和 ImageSharp 通常很好地支持我们System.Drawing.Common在非 Windows 环境中看到的用法。

System.Drawing.Common将仅在 Windows 窗体和 GDI+ 的上下文中继续发展。

要将这些 API 用于跨平台应用程序,请迁移到以下库之一:

或者,您可以通过在runtimeconfig.json文件中将System.Drawing.EnableUnixSupport 运行时配置开关设置为来启用对 .NET 6 中的非 Windows 平台的支持:true

JSON复制
{
   "configProperties": {
      "System.Drawing.EnableUnixSupport": true
   }
}

添加此配置开关是为了让严重依赖此包时间的跨平台应用程序迁移到更现代的库。但是,不会修复非 Windows 错误。此外,此开关已在 .NET 7 中删除。

 类似资料: