Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to load DLL 'e_sqlite3': The specified module could not be found

I have a Xamarin Forms solution. I added sqlite-net-pcl as reference to all projects. It works fine on Android but crashes on Windows 8.1 and Windows Phone 8.1. I have an IOS project but I don't have OSX at the moment to try it.

I use this in the Windows projects to access the database:

using System.IO;
using SQLite;
using Xamarin.Forms;
using HelloXamarin.Windows;
using Windows.Storage;

[assembly: Dependency(typeof(SQLiteDb))]

namespace HelloXamarin.Windows
{
   public class SQLiteDb : ISQLiteDb
    {
        public SQLiteAsyncConnection GetConnection(string databaseName)
        {
            var documentsPath = ApplicationData.Current.LocalFolder.Path;
            var path = Path.Combine(documentsPath, databaseName);
            return new SQLiteAsyncConnection(path);
        }
    }
}

Here are my references:

References

I get this exception when trying to access the database:

The type initializer for 'SQLite.SQLiteConnection' threw an exception.

Unable to load DLL 'e_sqlite3': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

  • at SQLitePCL.SQLite3Provider_e_sqlite3.NativeMethods.sqlite3_win32_set_directory(UInt32 directoryType, String directoryPath)
  • at SQLitePCL.SQLite3Provider_e_sqlite3..ctor()
  • at SQLitePCL.Batteries_V2.Init() at SQLite.SQLiteConnection..cctor()

I have no idea how to solve this, please help me!

The whole solution is available on GitHub: https://github.com/apspot/HelloXamarin

like image 828
Péter Aradi Avatar asked May 05 '17 18:05

Péter Aradi


3 Answers

For me, it worked by adding the e_sqlite3 bundle to the executable project

like image 117
tuke307 Avatar answered Oct 11 '22 18:10

tuke307


You need to add the SQLite Extensions.

  1. Go to Tools > Extensions and Updates
  2. Go to Online, then search for SQLite.
  3. Download SQLite for Windows Runtime

enter image description here

  1. In your Windows Project, Add Reference and ensure you add the extension.

enter image description here

Also remove Microsoft.VCLibs from your references.

like image 33
Adam Avatar answered Oct 11 '22 16:10

Adam


By this time the issue is still open. So before they come with some solid fix, you can use this work around, to solve the issue for now.

Add one helper class

using System;
using System.Diagnostics;
using System.IO;

namespace SQLitePCL
{
    public class NativeLibraryHack
    {
        public static bool Hacked { get; private set; }

        public static bool DoHack()
        {
            if (Hacked) return true;

            try
            {
                const string runtimeFolderName = "/runtimes";

                var destinationPath = typeof(SQLitePCL.raw).Assembly.Location
                    .Replace("\\", "/");
                var destinationLength = destinationPath.LastIndexOf("/", StringComparison.OrdinalIgnoreCase);
                var destinationDirectory = destinationPath.Substring(0, destinationLength) + runtimeFolderName;

                var sourcePath = new Uri(typeof(SQLitePCL.raw).Assembly.CodeBase)
                    .AbsolutePath;
                var sourceLength = sourcePath.LastIndexOf("/", StringComparison.OrdinalIgnoreCase);
                var sourceDirectory = sourcePath.Substring(0, sourceLength) + runtimeFolderName;

                if (Directory.Exists(sourceDirectory))
                    CopyFilesRecursively(new DirectoryInfo(sourceDirectory), new DirectoryInfo(destinationDirectory));
            }
            catch (Exception ex)
            {
                //Ignore Exception
                Debug.WriteLine(ex.Message);
                return false;
            }

            return (Hacked = true);
        }

        private static void CopyFilesRecursively(
            DirectoryInfo source,
            DirectoryInfo target
        )
        {
            foreach (var dir in source.GetDirectories())
                CopyFilesRecursively(dir, target.CreateSubdirectory(dir.Name));

            foreach (var file in source.GetFiles())
            {
                try
                {
                    var destinationFile = Path.Combine(target.FullName, file.Name);
                    if (!File.Exists(destinationFile))
                        file.CopyTo(destinationFile);
                }
                catch (Exception ex)
                {
                    //Ignore Exception
                    Debug.WriteLine(ex.Message);
                }
            }
        }
    }
}

And add the hack before your db migration script, I am using web api 2 so i did on RouteConfig.RegisterRoutes

    NativeLibraryHack.DoHack();

    using (KSDBContext db = new KSDBContext())
    {
        db.Database.Migrate();                 
    }
like image 42
Moumit Avatar answered Oct 11 '22 17:10

Moumit