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

2.0.5 breaks with .NET Framework 4.8 / Non-SDK-style / Mixed Platforms: Unable to load DLL 'e_sqlite3' #451

Closed JanZeman closed 2 years ago

JanZeman commented 2 years ago

Hello,

I am quite probably creating an issue very related (or even a duplicate?) to #389, #444 or #446. My hope is I will be able to provide some additional info that will try to fix a problem introduced in 2.0.5.

2.0.5 is actually the only thing I am 100% sure about. It connects the above issues and it was the version when I discovered the bug. When I try 2.0.6 issue is still reproducible. If I however rollback to 2.0.4 all is fine. The day I discovered this issue there was no any newer version of Frank Krueger's sqlite-net-pcl, it was on the same 1.7.335 version. My Xamarin based Android project is not affected by the same update. There it runs fine even after 2.0.5 upgrade.

I also figured out how to 'fix it', or work it around better said. Following the error message it is clear that the app cannot locate e_sqlite3.dll. My project is couple of years old and all those years the concrete platform specific e_sqlite3.dll was used from .\runtimes\win-x86\native\ or .\runtimes\win-x64\native\ subfolder. If I manually find the e_sqlite3.dll which I find in this subfolder and copy it 3 levels up in the folder hierarchy, i.e. next to the main executable .exe file the application runs as it used to do before.

To my (not very deep) understanding the 'old' way is the correct intended way. I can compare it for example to WebView2Loader.dll which my project also utilizes and there it is loaded correctly from the above named subfolder.

Platform: The old-fashioned classic .NET 4.8 of the main .exe. My solution has number of Class Libraries built with .NET Standard 2.0 target framework. OS: Windows 10 Debug, Mixed Platforms (When I try to build for x86, x64 or Any CPU the issue still reproduces)

Exception: The type initializer for 'SQLite.SQLiteConnection' threw an exception.
Inner exception: Unable to load DLL 'e_sqlite3': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
Source: SQLitePCLRaw.provider.e_sqlite3
Stack: 
   at SQLitePCL.SQLite3Provider_e_sqlite3.NativeMethods.sqlite3_libversion_number()
   at SQLitePCL.SQLite3Provider_e_sqlite3.SQLitePCL.ISQLite3Provider.sqlite3_libversion_number()
   at SQLitePCL.raw.SetProvider(ISQLite3Provider imp)
   at SQLitePCL.Batteries_V2.Init()
   at SQLite.SQLiteConnection..cctor()

   at SQLite.SQLiteConnection..ctor(String databasePath, SQLiteOpenFlags openFlags, Boolean storeDateTimeAsTicks)

Please let me know whether I can provide more usable info.

ericsink commented 2 years ago

Try 2.0.7-pre20210929171745 ?

JanZeman commented 2 years ago

Hi @ericsink,

Apologies for my delayed answer. I tried this new version and yes, the problem problem is fixed! To be sure I tested the android solution as well and that one stays working too.

If this change accepted should I expect 2.0.7 version in the following days / weeks? Best regards, Jan

lucahost commented 2 years ago

I was experiencing the same issue, after upgrading the problem was solved as well. no strange side-effects until now

MortenBoysen commented 2 years ago

I also want to add some information as well. As an example of our structure, we have a project and its dependents, where one is a test project. Both are targeting .NET Framework 4.8 and .NET 5. It looks something like this:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>net5.0;net48</TargetFrameworks>
    <AssemblyName>ProjectUsingSQLCipher</AssemblyName>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Data.Sqlite.Core" Version="5.0.10" />
    <PackageReference Include="SQLitePCLRaw.bundle_e_sqlcipher" Version="2.0.4" />
  </ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>net5.0;net48</TargetFrameworks>
    <IsPackable>false</IsPackable>
    <AssemblyName>ProjectUsingSQLCipher.Test</AssemblyName>
    <IsTestProject>true</IsTestProject>
  </PropertyGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'net48'">
    <!-- See https://github.com/dotnet/efcore/issues/19396 why we need to do this for .NET Framework-->
    <PackageReference Include="SQLitePCLRaw.bundle_e_sqlcipher" Version="2.0.4" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
    <PackageReference Include="xunit" Version="2.4.1" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\ProjectUsingSQLCipher\ProjectUsingSQLCipher.csproj" />
  </ItemGroup>

  <ItemGroup>
    <Content Include="xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
  </ItemGroup>
</Project>

For good measure, the xunit.runner.json file disables shadow copying. The setup above works well in both frameworks with SQLitePCLRaw.bundle_e_sqlcipher 2.0.4, though it is somewhat clunky that the dependency to SQLitePCLRaw.bundle_e_sqlcipher is not working transitively for .NET Framework 4.8. However, it works. When I tried to upgrade to version 2.0.5 or 2.0.6 the tests started to fail on .NET Framework 4.8 with the error described here and in the linked issues. I have tried to upgrade to 2.0.7-pre20210929171745 and can report that everything works. I can even delete the clunky

  <ItemGroup Condition="'$(TargetFramework)' == 'net48'">
    <!-- See https://github.com/dotnet/efcore/issues/19396 why we need to do this for .NET Framework-->
    <PackageReference Include="SQLitePCLRaw.bundle_e_sqlcipher" Version="2.0.4" />
  </ItemGroup>

and it still works on both .NET Framework 4.8 and .NET 5. That is fantastic!

I just want to finish with saying thanks for the great work, and I hope that 2.0.7 gets released soon. :-)

ericsink commented 2 years ago

2.0.7 is on nuget.org

JanZeman commented 2 years ago

Thank you @ericsink! I can only confirm 2.0.7 works and my project SQLite integration is flawless again :)