我有两个版本的System.Data.SQLite.DLL - 适用于x86和x64平台。 x86版本保留在应用程序文件夹中,x64版本保存在appFolder \ x64文件夹中。 编译为AnyCPU的应用程序。 如何根据Windows平台加载所需的SQLite版本?加载x86或x64程序集
回答
如果您正在使用SQLite从http://system.data.sqlite.org,该System.Data.SQLite.DLL完全管理。有一个底层原生DLL,SQLite.Interop.DLL,需要根据进程(32位或64位)进行更改。
我部署在“\本地\ X64" 本地库为64位和” \本地\ X86" 32位。在运行时P/Invoke SetDllDirectory设置DLL加载目录指向进程的正确路径。 http://msdn.microsoft.com/en-us/library/ms686203(v=vs.85).aspx
(请注意,我不熟悉的传统System.Data.SQLite.DLL版本从http://sqlite.phxsoftware.com架构)
private static class NativeMethods
{
[DllImport("kernel32.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern bool SetDllDirectory(string pathName);
}
...
// Underlying SQLite libraries are native.
// Manually set the DLL load path depending on the process.
var path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Native");
if(IntPtr.Size == 8) // or: if(Environment.Is64BitProcess) // .NET 4.0
{
path = Path.Combine(path, "X64");
}
else
{
// X32
path = Path.Combine(path, "X86");
}
NativeMethods.SetDllDirectory(path);
您可以使用Environment.Is64BitProcess来将进程标识为64位。 (我会尽量避免捕捉异常的流量控制尽可能。)
我很惊讶,这在所有工作。它应该首先找到x86版本并且失败。一个失败的程序集绑定不会通过AssemblyResolve产生另一个尝试。
显然,CLR实际上找不到x86版本,或者在x64模式下也会失败。换句话说,当你解决这个问题时,你会破坏64位代码。首先追踪x86问题,使用Fuslogvw.exe查看该程序集正在探测哪些文件夹。
一个真正的修复应该包括将x86程序集移动到一个单独的文件夹中,并相应地调整您的事件处理程序。您可以测试IntPtr.Size以确定您是否以64位模式运行(大小== 8)。此外,请确保生成完整的路径名称,使用现在使用的相对路径可能会导致应用程序的工作目录未设置在希望的位置。 Assembly.GetEntryAssembly()。位置为您提供EXE的路径。
- 在GAC中安装相应的DLL(例如,64位版本在一个64位平台上)
- 在你的web/app配置中使用程序集绑定(可能在机器配置中)
- 完全限定你的web/app配置中的任何部分程序集引用。
还有就是内置支持这1.0.80.0及更高版本。
如果开发和客户机器可能有不同的处理器体系结构,可能需要多个二进制包。对于这种情况,强烈建议使用本机库预加载功能。它从版本1.0.80.0开始可用,并且默认启用。(from download page)
但是,要获得它在我自己的工作插件我也有参考SQLite的首次之前,补充一点:
// Make SQLite work... (loading dll from e.g. x64/SQLite.Interop.dll)
System.Environment.SetEnvironmentVariable("PreLoadSQLite_BaseDirectory", System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location));
Sql.Data.SQLite...
看到这个问题:New SQLite mixed assemblies
一些反病毒程序阻止SetDllDirectory() - 花了很长时间才意识到这一点。 我们使用
System.Reflection.Assembly myass = System.Reflection.Assembly.GetExecutingAssembly();
FileInfo fi = new FileInfo(myass.Location);
System.IntPtr moduleHandle = LoadLibraryEx(fi.Directory.FullName + "\\x64\\SQLite.Interop.DLL", IntPtr.Zero, 0);
加载使用显式路径64 DLL。它在那个时候加载,并且.NET运行时将使用内存中的DLL,而不是在其中搜索磁盘。
Upvote for myass' :) – 2015-06-30 11:47:50
在我的情况下没有工作。即使我已经使用调试器进行了验证,但是本机库可以正确加载。 SQLite仍然抛出关于本地DLL丢失的异常。 – BartoszKP 2016-12-13 15:22:20
- 1. 根据平台加载x64或x86 DLL?
- 2. 在x86程序集中复制x64 MOVQ
- 3. JAVA SE x86或x64?
- 4. 使用并行程序集加载DLL的x64或x32版本
- 5. x86或x64反汇编LIB
- 6. Visual Studio加载正确的(x86或x64)dll!
- 7. Linux x64程序集
- 8. 如何处理x86与x64程序包
- 9. 针对x86和x64的安装程序?
- 10. 编译用于C#的X86/X64程序集#
- 11. 程序集:将x86代码转换为x64的简单例子
- 12. 程序集x86 movsb
- 13. 作为x86或x64运行的应用程序?
- 14. 我的(AT&T)程序集(x86-x64)代码应该增加,但不会
- 15. x64程序可以访问Windows x64上的x86 COM对象吗?
- 16. 在x64程序集中添加值
- 17. RXTX x64和x86
- 18. FASM - x64与x86
- 19. 程序集X86添加到结构中
- 20. x86程序集添加和移位
- 21. 将x86转换为x86-64程序集
- 22. .NET--无法为已加载的程序集加载文件或程序集
- 23. 无法加载文件或程序集
- 24. 无法加载文件或程序集
- 25. 无法加载文件或程序集
- 26. 无法加载文件或程序集
- 27. 无法加载文件或程序集
- 28. 无法加载文件或程序集
- 29. 无法加载文件或程序集
- 30. 无法加载文件或程序集
我已经解决了这个问题。谢谢。我用“IntPtr.Size == 8”。我使用AppDomain.CurrentDomain.AssemblyResolve代替SetDllDirectory。 – Rover 2011-05-20 10:18:27