Embedding SQLite.Interop.dll in C#

0

I have an application that has all the DLL files it needs embedded into it so that it is a standalone exe. Here is how I am loading everything now:

    public static Assembly ExecutingAssembly = Assembly.GetExecutingAssembly();
    public static string[] EmbeddedLibraries = ExecutingAssembly.GetManifestResourceNames().Where(x => x.EndsWith(".dll")).ToArray();
    public static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) {
        // Get assembly name
        var assemblyName = new AssemblyName(args.Name).Name + ".dll";

        // Get resource name
        var resourceName = EmbeddedLibraries.FirstOrDefault(x => x.EndsWith(assemblyName));
        if (resourceName == null) {
            return null;
        }

        // Load assembly from resource
        using (var stream = ExecutingAssembly.GetManifestResourceStream(resourceName)) {
            var bytes = new byte[stream.Length];
            stream.Read(bytes, 0, bytes.Length);
            return Assembly.Load(bytes);
        }
    }
    public static void Main(string[] arg) {
        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
        RealMain();
    }

So the first interesting thing I noticed is that it only loads the DLL files that are used in the first page. It isn't enough to put using System.Data.SQLite; at the top to get it to include System.Data.SQLite.dll, you also have to do something that touches that namespace right away.

The next issue involves SQLite.Interop.dll which it won't load into the assembly. When you try you get the following error:

Exception thrown: 'System.BadImageFormatException' in mscorlib.dll
An unhandled exception of type 'System.BadImageFormatException' occurred in mscorlib.dll
The module was expected to contain an assembly manifest. (Exception from HRESULT: 0x80131018)

Now I could unpack the DLL and copy it to the c:\Windows\System32 directory, but since everything else is self contained, it would be nice if this was as well. I noticed this SDK that claims to be able to create it as a virtual file:

https://www.boxedapp.com/boxedappsdk/usecases/embed_system.data.sqlite.dll_dependencies.html

Is there a way to do this without the extra SDK? Or as an alternative, is there another way of creating and using SQLite databases without that DLL using a different package? I tried 3-4 different packages yesterday and didn't get anywhere.

c#
sqlite
embedded-resource
asked on Stack Overflow Nov 21, 2019 by Alan

1 Answer

1

SOLUTION

Ok, so this is disappointing that it is so easy, and yet nowhere else did I see the solution in dozens of other SO questions. On the SQLite.org website, there are a couple different downloads to choose from. When you use the NuGet package manager, you get the wrong version if what you want to do is embed everything.

To do it right, go to: https://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki

On that page you will want to download the BUNDLE version. In my case that was sqlite-netFx46-static-binary-bundle-Win32-2015-1.0.112.0.zip

Manually add that as a resource, include in your application as an Embedded Resource (Those are 2 separate steps), set it to not copy to output directory and use the code from the question to have it added.

answered on Stack Overflow Nov 21, 2019 by Alan • edited Jun 20, 2020 by Community

User contributions licensed under CC BY-SA 3.0