【问题标题】:System.DllNotFoundException Unable to load DLL 'gdiplus.dll' error in a Windows containerSystem.DllNotFoundException 无法在 Windows 容器中加载 DLL 'gdiplus.dll' 错误
【发布时间】:2021-05-10 07:10:45
【问题描述】:

我们正在使用 Kubernetes (Amazon EKS) 的 Windows 容器上运行 .Net 核心控制台应用程序。主机操作系统为 Windows Sever 2016。Aspose.Cells 生成 excel 文件时出现以下错误。

System.TypeInitializationException: The type initializer for 'Gdip' threw an exception.   --->
System.DllNotFoundException: Unable to load DLL 'gdiplus.dll' or one of its dependencies: 
The specified module could not be found.

正如link 中所建议的那样,尝试使用 Windows 映像以便 GDI 库在容器中可用,但它不起作用。下面是docker文件,

FROM mcr.microsoft.com/windows:1809
FROM mcr.microsoft.com/dotnet/runtime:5.0
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
COPY ./ /App/WS
WORKDIR /App/WS
ENTRYPOINT ["dotnet", "AppService.dll"]

也试过下面的图片,但没有运气。

FROM mcr.microsoft.com/dotnet/aspnet:5.0
FROM mcr.microsoft.com/dotnet/sdk:5.0

FROM mcr.microsoft.com/windows/servercore:ltsc2019
FROM mcr.microsoft.com/dotnet/runtime:5.0

Linux 容器有显式安装 gdiPlus 库的选项,在 Windows 容器中找不到类似的东西。目前,我们希望仅在 Windows 容器上部署我们的应用程序。感谢任何帮助!

【问题讨论】:

    标签: .net-core gdi+ docker-image windows-container


    【解决方案1】:

    默认情况下,5.0 标记在面向 Windows 容器时为您提供 Windows Nano Server。此 Windows 的 SKU 已精简,不包含 gdiplus.dll。相反,您想要的是具有该 DLL 的 Windows Server Core。这记录在这里:https://github.com/dotnet/dotnet-docker/blob/main/documentation/scenarios/using-system-drawing-common.md

    根据我看到您引用的其他标签,您的目标似乎是 Windows Server 2019 用于您的容器。幸运的是,.NET 确实为 Windows Server Core 2019 提供了 .NET 5.0 映像。为此使用的标记是 5.0-windowsservercore-ltsc2019。您可以在https://hub.docker.com/_/microsoft-dotnet-runtime 找到此列表。这将是用于解决此问题的推荐标签。

    我怀疑您是否实际使用 Windows Server 2016 作为主机环境。没有任何版本的 Windows Server 能够使用比主机版本更新的 Windows 版本运行容器。此 Windows 容器版本兼容性矩阵在此处描述:https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/version-compatibility?tabs=windows-server-2016%2Cwindows-10-20H2

    我也对您的 Dockerfile 的内容感到有些困惑,因为您不断列出两个连续的 FROM 指令。例如,您发布了以下内容:

    FROM mcr.microsoft.com/windows:1809
    FROM mcr.microsoft.com/dotnet/runtime:5.0
    SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
    COPY ./ /App/WS
    WORKDIR /App/WS
    ENTRYPOINT ["dotnet", "AppService.dll"]
    

    第一条FROM 指令对生成的图像没有影响。 mcr.microsoft.com/windows:1809 基址在得到输出的图像中根本没有使用,因为在它之后有一个后续的 FROM 指令。您似乎正在尝试拉下mcr.microsoft.com/windows:1809 图像以用作mcr.microsoft.com/dotnet/runtime:5.0 图像的基础,但这不是它的工作原理。我鼓励您阅读 Dockerfile 结构。您可能也有兴趣了解如何将 .NET 安装到 .NET 未为其提供官方图像的其他图像类型。这有点像你在这里试图做的事情。但是在https://github.com/dotnet/dotnet-docker/blob/main/documentation/scenarios/installing-dotnet.md 上有关于如何做到这一点的官方指导。基本上,您可以像使用 mcr.microsoft.com/windows:1809 一样使用基本映像,并从其 zip 文件中显式安装 .NET。

    【讨论】:

    • 感谢详细解释!
    • Baga,你可以发布你最终得到的 docker 文件吗? (有类似的情况,Aspose.Cells + Core,在 gdiplus 上失败)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-13
    • 2011-01-06
    • 2017-06-11
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    • 2021-05-05
    相关资源
    最近更新 更多