Closed Ryan2065 closed 2 years ago
You might look at NativeLibrary.SetDllImportResolver()
. I think it would allow you to intercept DllImport
and specify where the native library is.
That worked! If you don't have docs anywhere, this would be helpful to have documented for people. Here's what I did:
The build puts the sqlite files in
NativeLibrary.SetDllImportResolver(typeof(SQLitePCL.SQLite3Provider_e_sqlite3).Assembly, NativeAssemblyResolver);
Then NativeAssemblyResolver is just this (note, PoshContextInteractions is the class name I'm in):
static IntPtr NativeAssemblyResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath)
{
if (!libraryName.Equals("e_sqlite3", StringComparison.OrdinalIgnoreCase))
return IntPtr.Zero;
var currentFolder = Path.GetDirectoryName(typeof(PoshContextInteractions).Assembly.Location);
IntPtr libHandle = IntPtr.Zero;
string dllPath = "";
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && RuntimeInformation.OSArchitecture == Architecture.X64)
{
dllPath = Path.Combine(currentFolder, "runtimes", "win-x64", "native", "e_sqlite3.dll");
}
else if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && RuntimeInformation.OSArchitecture == Architecture.X86)
{
dllPath = Path.Combine(currentFolder, "runtimes", "win-x86", "native", "e_sqlite3.dll");
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.OSArchitecture == Architecture.X64)
{
dllPath = Path.Combine(currentFolder, "runtimes", "linux-x64", "native", "libe_sqlite3.so");
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
dllPath = Path.Combine(currentFolder, "runtimes", "osx", "native", "libe_sqlite3.dylib");
}
if (File.Exists(dllPath))
{
NativeLibrary.TryLoad(dllPath, assembly, searchPath, out libHandle);
}
return libHandle;
}
Thanks for the help!
I'm working on a project where I run Entity Framework Core in PowerShell.
Because of this, all dll loads happen at runtime in a non-normal way. In general this isn't a huge deal, but for this library (well EntityFramework Core Sqlite), it cannot find e_sqlite3.
I've hooked up an assembly load context into
AssemblyLoadContext.Default.Resolving
and don't see this dll try to be loaded. I've also set a resolving method toAppDomain.CurrentDomain.AssemblyResolve
but don't see e_sqlite3 come in there.I can't just copy the .dll to base folder because this may run on Linux, Windows, or OSX. I know exactly where the right dll is programmatically (in base folder\runtimes\\native), I just need a way to tell SQLitePCL where it is.
How can I do that?