ericsink / SQLitePCL.raw

A Portable Class Library (PCL) for low-level (raw) access to SQLite
Apache License 2.0
512 stars 106 forks source link

DllNotFoundException: Unable to load DLL 'e_sqlite3' in MAUI Preview 11 #465

Closed pekspro closed 2 years ago

pekspro commented 2 years ago

When using this library in a MAUI Preview 11 project I got DllNotFoundException:

Unable to load DLL 'e_sqlite3' or one of its dependencies.

I found a solution for this. Open the csproj-file and replace:

<RuntimeIdentifier>win10-x64</RuntimeIdentifier>

With:

<RuntimeIdentifier>win-x64</RuntimeIdentifier>

Not sure if this is good, bad, a bug or a feature. I just wanted to share :-).

mldisibio commented 2 years ago

Ah. Such a good match to my recent observations! After updating my api packages, which reference SQLitePCLRaw.bundle_green 2.0.7, to .Net Core 6.0, I can run my application just fine when compiled with Visual Studio 2022. However, if you look at the /bin/Debug folder, VS does NOT copy or include the win10-x64 subdirectory, only win-x64 (and all the others of course), even though the win10-x64 directory is part of the nuget package folder structure.

When I run the exact same code and NuGet packages in the very well-known application 'LinqPad', I also get the Unable to load DLL (or dependencies) error, and the path it is referencing is \.nuget\packages\SQLitePCLRaw.lib.e_sqlite3\2.0.7\runtimes\win10-x64\nativeassets\net6.0-windows10\e_sqlite3.dll meaning LinqPad somehow identifies it's runtime as win10-x64.

Is there some issue with 2.0.7 where the win-x64 runtime assemblies all resolve correctly, but the win10-x64 runtimes do not?

Also, if I configure LinqPad to run the code as .Net 3.1, and reference 3.1 NuGet packages, which included SQLitePCLRaw.lib.e_sqlite3 2.0.4, everything resolves fine and the code runs, and there is an output of the assembly resolution which shows the native reference resolving to \.nuget\packages\SQLitePCLRaw.lib.e_sqlite3\2.0.4\runtimes\win-x64\native\e_sqlite3.dll

albahari commented 2 years ago

I've identified the bug. The following folder:

runtimes\win10-x64\nativeassets\net6.0-windows10

contains the UAP version of e_sqlite3.dll instead of the regular Win10 version. The UAP version should be in the following folder:

runtimes\win10-x64\nativeassets\uap10.0

You could also just remove the \net6.0-windows10 folder entirely - then the dll will be picked up from runtimes\win-x64\native folder, which seems to work fine.

mldisibio commented 2 years ago

@albahari Thank you so much Joe. While removing the net6.0-windows10 folder seems not to force LinqPad to pick up win-x64, replacing the _esqlite3.dll in runtimes\win10-x64\nativeassets\net6.0-windows10 with the version from .\runtimes\win-x64\native did compile and run as expected!

cc @ericsink

albahari commented 2 years ago

While removing the net6.0-windows10 folder seems not to force LinqPad to pick up win-x64

This is purely a caching issue - removing the net6.0-windows10 folder will definitely force LINQPad to pick up win-x64 (as is did in version 2.0.6 which didn't have the net6.0-windows10 folder). You can verify this by deleting LINQPad's cache in %localappdata%\LINQPad\NuGet.NetCore.PerfCache.

ericsink commented 2 years ago

This is good detective work, thanks.

Unfortunately, the implementation of this stuff recently changed, so I'll need to revisit this issue to make sure the new implementation doesn't bring-back the problem. While I was working on that code recently, I did notice that it seemed like UAP support was probably broken in 2.0.7 and wondered why nobody noticed. :-)

ericsink commented 2 years ago

The discussion in #477 is relevant here.

albahari commented 2 years ago

For now, I'm adding the following code to LINQPad's NuGet runtime directory prober:

 ...where !ID.EqualsNoCaseOrdinal ("SQLitePCLRaw.lib.e_sqlite3") ||
           Version.ToString() != "2.0.7" ||
           !ridDir.Name.StartsWithOrdinal ("win10", true)

Obviously, it's not a long-term solution.

pekspro commented 2 years ago

In MAUI RC1 these lines has to be removed from the .csproj-file:

<PropertyGroup Condition="$(TargetFramework.Contains('-windows'))">
    <OutputType>WinExe</OutputType>
    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>

Otherwise, you get a strange exception when the application starts (see https://github.com/dotnet/maui/issues/6063).

And SQLitePCLRaw.bundle_e_sqlite3 needs to be updated to version 2.1.0-pre20220318192836:

<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.0-pre20220318192836" />
VladislavAntonyuk commented 2 years ago

@ericsink I think this also can be closed