26

Previously .NET SQLite libraries were available from http://sqlite.phxsoftware.com, but they have recently been taken over by the main SQLite team and have moved System.Data.SQLite Download Page. The new packages don't seem to contain mixed assemblies anymore (single assembly containing sqlite3.dll and the .NET wrapper).

The new package comes with the .NET DLL and SQLite.Interop.dll which based on the documentation is not needed on the desktop but my application fails to load with Unable to load DLL 'SQLite.Interop.DLL': The specified module could not be found.. I have tried running the application under IIS/IIS Express with apppool set to 32-bit.

I have tried copying the SQLite.Interop.dll file into the bin folder, the system folder, and the ASP.NET temp folder but still get the same error.

Are there mixed assemblies for new releases available anywhere? If not, is there a way to fix the Unable to load DLL 'SQLite.Interop.DLL error?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
kay.one
  • 7,622
  • 6
  • 55
  • 74
  • Yes, that said, I can't switch to x64 assemblies for sqlite as I need the same package to work on both 32 and 64 bit. – kay.one Jun 01 '11 at 18:39

4 Answers4

23

The downloads page now contains "mixed mode" downloads for all variations of System.Data.SQLite, that work the same way as earlier versions of SQLite i.e. no requirement to also include SQLite.Interop.dll in your project.

The trick is - look for the word "bundle" in the download links

e.g. sqlite-netFx35-setup-bundle-x86-2008-1.0.76.0.exe

You will also see that the description text for these links begins with "This setup package features the mixed-mode assembly".

I got burned because I didn't realize that this really means "download this one if you want it to work the way it always did before".

Having no idea what was meant by a mixed-mode assembly, the other links seemed like a better option - because they claim "This setup package will install all the necessary runtime components and dependencies".

Also note that the only way to tell if you've gotten the "wrong" one is by file size. The DLLs have exactly the same name, and exactly the same version number. The mixed-mode version is much bigger - around 700K. The other one is around 160K.

What a mess...

Tom Bushell
  • 5,865
  • 4
  • 45
  • 60
  • 1
    For some reason, they seem to discourage the use of bundle packages though: "These packages should only be used in cases where the assembly binary must be deployed to the Global Assembly Cache for some reason (e.g. to support some legacy application on customer machines)" – Nicolas Raoul May 30 '13 at 07:53
  • 3
    It looks like they have added a new feature since I wrote my answer - "native library pre-loading...as of version 1.0.80.0". But it's not at all clear to me why this is better, or why what used to be a simple single-DLL database has become so complicated. – Tom Bushell May 30 '13 at 18:24
  • plus won for "what a mess" – philologon Apr 30 '15 at 21:40
  • I had to specifically get the Interop DLL from the binary zip file. Once I used the Interop DLL in the binary distribution, it was smooth sailing following the recommendation here: https://stackoverflow.com/a/19123510/1686511 – Garry Polley May 25 '17 at 20:12
18

I found the solution. The problem was due to a known issue with SQLite.Interop.dll.

This is the workaround from that worked for me.

Using Dependency Walker from http://dependencywalker.com/ to look at SQLite.Interop.dll (x86 and x64) shows that it depends on MSVCR100.dll.

The old 1.0.66.0 version of System.Data.SQLite.dll does not have this dependency. With the current build, we would have to redistribute that MSVCR100.dll also or run an installer from Microsoft.

Solution: From: Missing msvcr100.dll

Use static linking. In the SQLite.Interop Visual Studio project. Go to this Properties setting: Project -> Properties -> Configuration Properties -> C/C++ -> Code Generation -> Runtime Library and change the value to Multi-threaded (/MT). (The current source code (1.0.71.0) has Multi-threaded DLL (/MD) which causes the dll to rely on MSVCR100.dll and the DLLImport (and LoadLibary()) to fail when users do not have it).

I believe static linking should be changed so it is the default for SQLite.Interop.dll.

Community
  • 1
  • 1
kay.one
  • 7,622
  • 6
  • 55
  • 74
  • Worth noting as well that if rebuilding isn't an option, then the MSVC 2010 runtime (for x86) can be downloaded from http://www.microsoft.com/download/en/confirmation.aspx?id=5555 ... there will almost certainly be an x64 version as well. – Chris J Oct 24 '11 at 15:34
  • 3
    I'm struggling with this right now. If I understand correctly, it seems we've lost one of the really nice things about SQLite - a single DLL deployment. If so, that really sucks... – Tom Bushell Nov 02 '11 at 21:50
  • If not using the static package, make sure you have the VC++ runtime (http://support.microsoft.com/kb/2019667). If it still fails, make sure SQLite.Interop.DLL is in the same directory as System.Data.SQLite.dll, or VS won't be able to find this second file. – Gulbahar Feb 26 '13 at 16:36
8

I had the same issue, in a plugin for a different application. In my case I solved it by modifying the environment variable PreLoadSQLite_BaseDirectory before referencing SQLite for the first time.

// Make SQLite work... (loading dll from e.g. x64/SQLite.Interop.dll)
System.Environment.SetEnvironmentVariable("PreLoadSQLite_BaseDirectory", System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location));

Sql.Data.SQLite...

I don't see why this was required though, as I thought PreLoadSQLite_BaseDirectory (well, the corresponding internal variable) would default to the location of the System.Data.SQLite.dll file.

Grilse
  • 3,491
  • 2
  • 28
  • 35
johv
  • 4,424
  • 3
  • 26
  • 42
4

On 64-bit machines an AnyCPU targeted .NET application cannot load 32-bit DLL files. You likely will need to set the platform target of your .NET application to x86 in order to get it working on both the 64-bit and 32-bit machines.

Edit: under the hood the reason you can't load the Interop DLL is probably because of a BadImageFormatException due to the bitness mismatch with the native SQLite DLL file.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user7116
  • 63,008
  • 17
  • 141
  • 172
  • my app is targeted at x86, and when I look at task manager the process has a * in front which means that it is running under WOW (I assume) – kay.one Jun 01 '11 at 19:14
  • Then the SQLite Interop DLL is NOT targetted at x86 and instead is AnyCPU. – user7116 Jun 01 '11 at 19:16
  • Is there a tool that would tell me the target for an assembly? – kay.one Jun 01 '11 at 19:25
  • I downloaded the *x86 SQLite* from your link. Created a new *x86* C# Console project. Added `System.Data.SQLite.dll` as a reference. I then added `SQLite.Interop.dll` as an existing item to my project. Made it *Content* (*Copy if Newer*). Runs without exception on my 64bit Win7 machine as a 32bit program. Also runs on my 32bit XP machine. If I make the Console Project *AnyCPU* it fails. – user7116 Jun 01 '11 at 19:27
  • @Keivan: sure you can use `corflags.exe `(http://msdn.microsoft.com/en-us/library/ms164699.aspx) to inspect the target. – user7116 Jun 01 '11 at 19:30
  • I'm actually running under IIS/IISExpress, but I have the apppool set to 32bit. – kay.one Jun 01 '11 at 20:29
  • In case you are interested, the source for the app in question is available at https://github.com/kayone/NzbDrone – kay.one Jun 01 '11 at 20:34
  • AppPool, hmm, you've reached beyond my expertise. Going to retag your question. – user7116 Jun 01 '11 at 20:54