in

System.Data.SQLite

An open source ADO.NET provider for the SQLite database engine

Rebuild assemblies with a different name and SQLITE_DLL for side by side x86/x64 ?

Last post 11-04-2009 6:50 AM by Krzys. 0 replies.
Page 1 of 1 (1 items)
Sort Posts: Previous Next
  • 11-04-2009 6:50 AM

    • Krzys
    • Not Ranked
    • Joined on 11-04-2009
    • Posts 1

    Rebuild assemblies with a different name and SQLITE_DLL for side by side x86/x64 ?

    Hello,

    I am trying to use SQLite.NET in both 32 AND 64 bits environments, in a scenario where I cannot force my process in 32 bit (must run in 64 bit native), and where the deployment is xcopy-based (same files, no way to choose during install time between the two versions, and no way of knowing before hand what OS version will be present).

    Right now, I'm using the AppDomain.CurrentDomain.AssemblyResolve to load the correct version (x64 or x86) from two different folders, and it works well:

    In a static constructor somewhere (called before any reference to the sqlite types):

        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

    And in the same class:

        static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            if (args.Name.StartsWith("System.Data.SQLite, ", StringComparison.OrdinalIgnoreCase))
            {
                string realName = IntPtr.Size == 8 ? "./libs/x64/System.Data.SQLite.dll" : "./libs/x86/System.Data.SQLite.dll";
                return System.Reflection.Assembly.LoadFile(realName);
            }
            return null;
        }
    The only problem is that, for this to work, the assemblies MUST be named "System.Data.SQLite.dll", if not all interop calls will fail (because DllImport is referencing this name). If i rename them "System.Data.SQLite.x86.dll" and "System.Data.SQLite.x64.dll", the Assembly.LoadFile will succeed, but not query execution, because it will still look for a file with the original name when trying to load the native code.

    Also my biggest problem is with upgrading previously installed versions of my app. Before using the above trick, I worked around the 64 bit problem by using two differents providers: Mono.Data.Sqlite.dll for 32-bit, and the 64-bit version of System.Data.Sqlite.dll in x64, with the code using one or the other at runtime (by checking if IntPtr.Size == 8 or 4). But I found to many blocking bugs in the mono version that forced me to migrate to SQLite.NET.

    It worked as a temporary fix, but now I have the situation where all my deployed apps have the 64 bit version deployed on all machines (wether 32 or 64 bits), in the same folder as my app, and so it will be automatically loaded by the runtime, and my AssemblyResolve event will not be triggered. 

    What I think would a solution would be to build two versions of SQLite.NET, named "System.Data.SQLite.x86.dll" and "System.Data.SQLite.x86.dll", each with a different value defined for the constant SQLITE_DLL (in UnsafeNativeMethods.cs) matching the new names. In a static constructor somewhere, I would manually load the correct assembly in the AppDomain, before referencing any types, to be sure that the runtime would not try to load any previously deployed version.

    Also, in my Visual Studio projects referencing SQLite.NET, i would use the managed only dll (so i would have no warnings on 64 bits dev machines), configured with "Copy Local = false", and with some magic in the PostBuild events, copy the two customs dll in the target path (already doing that, btw)

    Only problem is that i can't seem to be able to build the combined assemblies (the x86 and x64 versions) with Visual Studio 2008. I was not able to find any information on how to build theses two dll.

    Any idea ?

    Basically all I need is to rebuild the assemblies with the following code change in UnsafeNativeMethods.cs, and clone the Release configurations to Release32 and Release64 that would use a different AssemblyName and output folders.

    #if BUILD_CUSTOM_X64
        private const string SQLITE_DLL = "System.Data.SQLite.x64.DLL";
    #elif BUILD_CUSTOM_X86
        private const string SQLITE_DLL = "System.Data.SQLite.x86.DLL";
    #else
        private const string SQLITE_DLL = "System.Data.SQLite.DLL";
    #endif

    Any help would be really appreciated !


Page 1 of 1 (1 items)
Powered by Community Server (Commercial Edition), by Telligent Systems