Supporting .NET SQLite on 32 and 64-bit systems

By | April 12, 2013

I’m trying to finally get the Yats application to compile and run on both x86 and x64 Windows versions with a single build. The only library giving problems is System.Data.SQLite. I found an almost complete solution in stackoverflow.  Here is a quick reminder on how to set up the Visual Studio project. I added the following code in my DAO class before starting to create any SQLite objects:


private static class NativeMethods
{
[DllImport("kernel32.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern bool SetDllDirectory(string pathName);
}

public void Init()

{

// Underlying SQLite libraries are native.
// Manually set the DLL load path according to the architecture
var path =  Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Native");
if (IntPtr.Size == 8) // check for 32/64 bits
{
path = Path.Combine(path, "X64");
}
else
{
// X32
path = Path.Combine(path, "X86");
}
NativeMethods.SetDllDirectory(path);

}

The SQLite libraries can be downloaded here. I use the sqlite-netFx35-binary-Win32-2008-1.0.84.0.zip and sqlite-netFx35-binary-x64-2008-1.0.84.0.zip. The ‘bundle’ packages do not contain the SQLite.Interop.dlls, not recommended in the download page.

The project directory structure after extracting the DLLs is:

Logging.SQLite (project directory)
    Native
        X64
            SQLite.Interop.dll
            System.Data.SQLite.dll
            System.Data.SQLite.Linq.dll

        X86
            SQLite.Interop.dll
            System.Data.SQLite.dll
            System.Data.SQLite.Linq.dll

The Visual Studio project properties for these DLLs are set to ‘Copy if newer‘. There is also a reference to one of the System.Data.SQLite.dll but I had to set the ‘Copy Local‘  property of the reference to false. Otherwise I get an exception during load: ‘The module was expected to contain an assembly manifest‘. I will try to test this approach on more PCs and update this article if more problems are found.

Please leave a comment how it is working for you

UPDATE:

The SetDllDirectory does seem to fail. Another, very similar approach is to register an AssemblyResolve handler.


public void Init()
{

AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
// do your SQLite init here
AppDomain.CurrentDomain.AssemblyResolve -= OnAssemblyResolve;

}

private static Assembly OnAssemblyResolve(object sender, ResolveEventArgs e)
{
if (e.Name.StartsWith("System.Data.SQLite,", StringComparison.OrdinalIgnoreCase))
{
// Underlying SQLite libraries are native.
// Manually set the DLL load path according to the architecture.
var path = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "Native");
if (IntPtr.Size == 8) //
{
path = Path.Combine(path, "X64");
}
else
{
// X32
path = Path.Combine(path, "X86");
}

string fileName = Path.Combine(path, "System.Data.SQLite.dll");
return Assembly.LoadFile(fileName);
}
return null;
}

One thought on “Supporting .NET SQLite on 32 and 64-bit systems

  1. MegaMilivoje

    Nice article! I have been searching for a complete solution. Thanks

    Reply

Leave a Reply

Your email address will not be published.