“无法加载 DLL 'SQLite.Interop.dll' 或其依赖项之一”运行 Docker 中的一个应用程序,但在本地它工作正常

“Unable to load DLL 'SQLite.Interop.dll' or one of its dependencies” running an application in Docker, but locally it works fine

简介

SQLite.Interop.dll 库似乎经常出现问题。只需看看这些其他 Whosebug 问题:

我已经完成了以上所有以及更多内容:

没有成功。关键因素是应用程序 运行 在本地运行良好,但我需要在 Docker 上实现 运行,这就是问题所在开始。情况是我正在使用 Visual Studio 2022 开发 .NET Core 3.1 控制台应用程序。该应用程序最终将部署在 AKS (Azure Kubernetes Service) 上。当然,首先我需要让它在我的开发机器上本地安装的 Docker 上运行。 在 Visual Studio 上构建 控制台应用程序项目没有给我任何错误,并且 运行 从 Visual Studio 开始就没问题了。 构建其Docker图像与适当的Docker文件也没有问题,但是运行宁 Docker 上的相同图像引发以下异常:Unable to load DLL 'SQLite.Interop.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)。目前,该项目安装了 System.Data.SQLite.Core NuGet 包,并且 *.csproj 中没有 these 元素。异常是由控制台应用程序之一引用的项目引发的;该项目同时安装了 System.Data.SQLite.CoreSystem.Data.SQLite NuGet 包。控制台应用程序的项目只安装了 System.Data.SQLite.Core 包(我已经尝试安装 System.Data.SQLite,但没有成功)。 所有项目现在都安装了 System.Data.SQLite NuGet 包(试一试),这导致 System.Data.SQLite.Core 作为依赖项安装

我试过的

我使用了 Visual Studio 2022 预组装的 Dockerfile,它处理了所有各种参考项目:

FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /src
COPY ["ProjectA/ProjectA.csproj", "ProjectA/"]
COPY ["ProjectB/ProjectB.csproj", "ProjectB/"]
#COPY all the other referenced projects
RUN dotnet restore "ProjectA/ProjectA.csproj"
COPY . .
WORKDIR "/src/ProjectA"
RUN dotnet build "ProjectA.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "ProjectA.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ProjectA.dll"]

由于此 Docker 文件基于 多阶段构建 ,因此它包含以下行:

...
RUN dotnet build "MyProject.csproj" -c Release -o /app/build
...
RUN dotnet publish "MyProject.csproj" -c Release -o /app/publish
...

先构建代码,再发布。考虑到 dotnet publish,我决定退后一步,确保至少我能够自己发布该项目,以缩小问题范围。我发现在本地文件夹上发布它也给我带来了一些问题,尤其是 NU1605 error, which was preventing me to end the process successfully. I resolved the issue using what Microsoft suggests。现在,如果我 运行 位于发布目标文件夹内的 .exe,应用程序将按预期工作

是时候最终将其制作成 Docker 图像了。镜像构建过程很顺利,但是在运行的时候出现了Unable...的错误。网上看,为了解决SQLite.Interop.dll的问题,他们建议SQLite.Interop.dll文件直接移动到bin文件夹;事实上,最初,我发现它位于 bin\Release\netcoreapp3.1\runtimes\ 文件夹中,在其 win-x86win-x64 子目录中。为了“摆脱”这个 runtimes 文件夹,我尝试使用以下设置在本地文件夹上发布项目:

这实际上使 SQLite.Interop.dll 直接出现在 bin 文件夹中,并摆脱了 runtimes 文件夹 。因此,为了获得与 Docker 相同的结果,我修改了 Docker 文件,如下所示:

...
RUN dotnet build "MyProject.csproj" -c Release -o /app/build -r win-x64
...
RUN dotnet publish "MyProject.csproj" -c Release -o /app/publish -r win-x64
...

现在 SQLite.Interop.dll 文件也直接出现在 Docker 运行ning 容器的 bin 文件夹中,所以我当时认为一切都很好,但我仍然遇到异常。

最后一件事

我发现 运行 在本地(不在 Docker 中)未指定目标 运行 时间(因此,将构建过程保持为 Any CPUx64),引发 无例外(也就是说,保留 runtimes/ 文件夹和其中的两个 SQLite.Interop.dll 文件,在 win-x86win-x64 子文件夹)。

我最终切换到 Linux 容器。