skip to Main Content

Introduction

There seems to be frequent issues with the SQLite.Interop.dll library. Just look at these other StackOverflow questions:

I’ve gone through all of the above and more:

  • I installed the System.Data.SQLite.Core NuGet package,
  • I specified these elements in the *.csproj,
  • I set x64 instead of Any CPU,
  • and so on

with no success. The key element is that the application runs just fine locally, but I need to make it run on Docker, and that’s where the problems start. The situation is that I’m working on a .NET Core 3.1 console application with Visual Studio 2022. The application will be finally deployed on AKS (Azure Kubernetes Service). Of course, first I need to make it work on the local installation of Docker in my development machine. Building the console application project on Visual Studio gives me no error and it runs fine from Visual Studio. Building its Docker image with the appropriate Dockerfile also gives no problems, but running the same image on Docker raises the following exception: Unable to load DLL 'SQLite.Interop.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E). Currently, the project has the System.Data.SQLite.Core NuGet package installed and doesn’t have these elements in the *.csproj. The exception is raised by a project referenced by the one of the console application; this project both has the System.Data.SQLite.Core and System.Data.SQLite NuGet packages installed. The console application’s project has only the System.Data.SQLite.Core package installed (I already tried to install also the System.Data.SQLite, with no success). All the projects, now, has the System.Data.SQLite NuGet package installed (to give it a try), which causes the System.Data.SQLite.Core to be installed as a dependency.

What I tried

I used the Dockerfile pre-assembled by Visual Studio 2022, which deals with all the various referenced projects:

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"]

Since this Dockerfile is based on a multi-stage build, it has the following lines:

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

to first build the code, and then publish it. Given that dotnet publish, I decided to take a step back and be sure that, at least, I was able to publish the project myself, to narrow down the issue. I found that publishing it locally on a folder also gave me some problems, in particular the NU1605 error, which was preventing me to end the process successfully. I resolved the issue using what Microsoft suggests. Now, if I run the .exe located inside the publish destination folder, the application works as expected.

It was time to finally make it a Docker image. The image building process went well, but then the Unable... error appeared at runtime. Reading online, to solve the SQLite.Interop.dll issue, they suggest to move the SQLite.Interop.dll file directly in the bin folder; in fact, originally, I found it lived inside the binReleasenetcoreapp3.1runtimes folder, both in its win-x86 and win-x64 sub-directories. To “get rid” of this runtimes folder, I tried to publish the project locally on a folder, with the following settings:

![enter image description here

This in fact made the SQLite.Interop.dll appear directly inside the bin folder and got rid of the runtimes folder. So, to obtain the same result with Docker, I modified the Dockerfile like this:

...
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
...

and now the SQLite.Interop.dll file appears directly also inside the bin folder in the Docker running container, so I thought everything was just fine at that time, but still I got the exception.

One last thing

I found that running the application locally (not in Docker) without specifying the destination runtime (so, keeping the build process as Any CPU instead of x64), raised no exceptions (that is, keeping the runtimes/ folder and the two SQLite.Interop.dll files inside of it, in the win-x86 and win-x64 sub-folders).

3

Answers


  1. Chosen as BEST ANSWER

    I ended up switching to Linux containers.


  2. Solution

    To run a dotnet application (e.g. dotnet test) inside a windows docker container with the System.Data.SQLite.Core nuget package you can use the following docker file

    # escape=`
    FROM mcr.microsoft.com/windows/servercore:ltsc2019
    
    RUN setx /M PATH "%PATH%;C:Program Filesdotnet;C:nodejs"
    
    # Install Microsoft Visual C++ Runtime Library
    SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop';$ProgressPreference='silentlyContinue';"]
    
    # Install .NET 6.0 for x86 (just change it to the platform you need)
    RUN Invoke-WebRequest `
                -UseBasicParsing `
                -Uri https://dot.net/v1/dotnet-install.ps1 `
                -OutFile dotnet-install.ps1; `
            ./dotnet-install.ps1 `
                -InstallDir '/Program Files/dotnet' `
                -Channel 6.0 `
                -Architecture x86 
    
    

    Here is the releveant part of my csproj file:

       <ItemGroup>
          ...
          <PackageReference Include="System.Data.SQLite.Core" Version="1.0.117" />
        </ItemGroup>
    

    What worked for me

    After switching to the script method, to install the .NET framework (and not using the binary) it worked for me.

    Beforehand, like you, I tried a ton of different things!

    What you can try

    What might work is also to add the PrivateAssets="none" in the csproi. See this answer. After adding this to the csproj files I got a different error, because I must use a x86-dll in my project.

    After installing .NET 6 x86 correctly, I reverted even this change in the csproj and it still worked!

    What else

    What I also tried, but was not necessary in the end, was Microsoft Visual C++ Runtime Library.

    Quote from https://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki

    All downloadable packages on this web page that do not include the word "static" in their file name require the appropriate version (e.g. 2005, 2008, 2010, 2012, 2013, 2015, 2017) of the Microsoft Visual C++ Runtime Library, to be successfully installed on the target machine, prior to making use of the executables contained therein.

    ...
    # Install Microsoft Visual C++ Runtime Library
    SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop';$ProgressPreference='silentlyContinue';"]
    RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; `
        Invoke-WebRequest "https://aka.ms/vs/17/release/vc_redist.x64.exe" -OutFile "vc_redist.x64.exe"; `
        Start-Process -filepath C:vc_redist.x64.exe -ArgumentList "/install", "/passive", "/norestart" -Passthru | Wait-Process; '
        Remove-Item -Force vc_redist.x64.exe;
    

    More information on How-To install .NET in a docker container can be found at the dotnet-docker github repo

    TL/DR

    Use dotnet-install.ps1 in your dockerfile to install .NET and the SDK. Somehow, it does some magic, so that you can run dotnet apps which are using the SQLite.Interop.dll library (included via nuget)

    Login or Signup to reply.
  3. We have experienced the issue updating from System.Data.SQLite.Core 1.0.113.6 to 1.0.117.

    Locally and in build pipeline everything works fine, but as soon as our app deployed in a docker container running mcr.microsoft.com/dotnet/runtime:6.0-nanoserver-1809 image – application throws the named exception Unable to load DLL 'SQLite.Interop.dll': The specified module could not be found.

    I found this thread at sqlite forum which clarified the situation a bit: https://sqlite.org/forum/info/0c471ca86ae7a836

    Quote from the forum:

    This actually seems to be caused by some extra dependencies in the
    latest version of SQLite.Interop.dll.

    Using dumpbin I compared the dependencies between version 1.0.113.7
    and 1.0.114.4 and these new dependencies were added:

    mscoree.dll
             1801473F0 Import Address Table
             180186090 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference
    
                          6F StrongNameSignatureVerificationEx
                          71 StrongNameTokenFromAssembly
                          62 StrongNameFreeBuffer
                           F CorBindToRuntimeEx
                          61 StrongNameErrorInfo
    
    WINTRUST.dll
             1801473E0 Import Address Table
             180186080 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference
    
                          82 WinVerifyTrust 
    

    mscoree.dll is not available in in the mcr.microsoft.com/dotnet/core/runtime image I was
    using. If I copy it in from a different image, SQLite.Interop.dll is
    loaded successfully

    We ended up reverting back to version 1.0.113.6 as we didn’t want to introduce extra complexity to docker image. I hope the issue with the latest System.Data.SQLite.Core will be resolved in one of the coming versions.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search