无法加载 DLL 'SQLite.Interop.dll'

259

我定期遇到以下异常:

无法加载 DLL 'SQLite.Interop.dll':找不到指定的模块。 (HRESULT 的异常来自:0x8007007E)

我正在使用 1.0.82.0 版本,通过 nuget 在 VS2010 中安装它,在操作系统 Win7 64 上运行。

一旦异常开始出现,它就会在调试和发布以及在 VS 内部或外部运行应用程序时不断出现。

唯一停止它的方法是注销并重新登录。异常不会被抛出且 DLL 已加载。 它可以工作几天,但然后可能再次中断。

是否有人看过这样的情况并且有解决办法?


2
是的,它被设置为始终复制。我在bin/debug中有x64和x86文件夹。它大多数时候都能正常工作,但有时会突然停止工作。可能是某些东西阻止了对dll的访问,下次它停止工作时我会尝试找出原因。就像我说的,它可能连续几天都没有任何问题。 - xll
19
在将SQLite nuget包添加到新的控制台项目后,我立即遇到了这个错误。从x86文件夹手动复制SQLite.Interop.dll文件到上一级目录可以让应用程序运行。我觉得这很奇怪,竟然会出现这种问题。 - lesscode
1
如果您下载了正确的SQLite二进制文件,则根据您的项目构建选项将SQLite.Interop.dll复制到Release或Debug文件夹中。 - Elshan
对我来说,在运行和调试时它可以工作,但在d:DesignInstance (wpf)上不行。我通过将dll复制到项目目录中来修复它,但重新启动后,它就不再起作用了。我不明白。 - Patrick
好的...我把它改成了仅限x86 - 仍然不起作用。撤销更改...他妈的,它工作了! - Patrick
显示剩余3条评论
49个回答

9
这里有很多答案,但我的回答简单明了,没有混乱的GAC。
问题在于,可执行文件需要一个正确的SQLite.Interop.dll副本(x86或x64)才能访问我们的数据库。
大多数体系结构都有层,并且在我的情况下,Data Layer具有SQLite连接所需的DLL。
因此,我在Data Layer解决方案中简单地添加了一个后建脚本,一切正常运行。
TL;DR;
将解决方案的所有项目设置为x86或x64。
向使用SQLite nuget包的项目添加以下后建脚本:
xcopy "$(TargetDir)x64" "$(SolutionDir)bin\Debug\" /y
当然,你需要为发布版本和x86构建更改脚本。
STL;DR;
将SQLite.Interop.dll放置在.exe文件旁边。

7
默认安装的NuGet多架构(x86,x64)版本SQLite表现出您所描述的行为。如果您想加载实际体系结构的正确版本,即.NET运行时选择在您的计算机上运行应用程序的体系结构,则可以按以下方式向DLL加载器提示正确库的位置:
在Program.Main()之前添加对kernel32.dll函数调用SetDLLDirectory()的声明:
    [System.Runtime.InteropServices.DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Unicode, SetLastError = true)]
    [return: System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)]
    static extern bool SetDllDirectory(string lpPathName);

然后使用自己的方法来确定正确的子目录以找到特定体系结构版本的 'SQLite.Interop.dll'。 我使用以下代码:

    [STAThread]
    static void Main()
    {
        int wsize = IntPtr.Size;
        string libdir = (wsize == 4)?"x86":"x64";
        string appPath = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
        SetDllDirectory(System.IO.Path.Combine(appPath, libdir));

5
我不知道为什么这个还没有被包含,但我不得不自己进行研究并找到答案,希望有人能找到这个答案并免去麻烦。这是一个WPF应用程序。在我的开发机上运行得很好,但在我复制它并出现“无法加载DLL'SQLite.Interop.dll'”错误的计算机上却无法正常工作。当我运行它时,我将其所有关联目录和文件直接从我的“Debug”文件夹移植到这台其他计算机上,但我遇到了与OP相同的错误。当我使用此路径复制我的DLL的“bin”文件夹到“Debug\bin”中,并包括所有应用程序文件时,它没有缺少任何文件。
其他答案中提到但不适用的事项:
  • 我没有使用NuGet包,也不需要创建x86或x64文件夹,这似乎是NuGet包创建的。我的DLL(System.Data.SQLite和SQLite.Interop.dll以及System.Data.SQLite.config)位于项目的“bin”文件夹中,并且是手动复制的(在VS的解决方案资源管理器中创建一个“bin”文件夹,在Windows资源管理器中将DLL粘贴到此文件夹中,使用“添加>现有项”将文件带入VS文件夹/项目)。然后,我在项目中引用它们作为引用程序使用该位置(“引用” > “添加引用”,并浏览到一个,重复其余的)。这确保了我的项目知道它们的确切位置。
  • 我不需要在我的app.config中引用任何SQLite DLL文件,甚至不需要触摸我的MyProject.csproj文件。
  • 我甚至不需要指定特定的处理器!我的项目构建为“任何CPU”,即使我只有混合或64位DLL,并且只会在运行Windows 7+的64位OS上运行。(没有仅限x86 / 32位的DLL)
  • 当我遇到OP的错误时,我已经将它们指定为“内容”和“如果更新则复制”的这些DLL。
我发现了这个来自https://system.data.sqlite.org/index.html/doc/trunk/www/faq.wiki#q20的内容:
(11)为什么在运行应用程序时会出现DllNotFoundException(针对“sqlite3.dll”或“SQLite.Interop.dll”)?

命名的动态链接库(DLL)无法定位或由于缺少依赖项而无法加载。确保命名的动态链接库位于应用程序目录或系统PATH沿着的目录中,并重试。此外,请确保已安装必要的Visual C++运行时可再分发,除非您使用的是静态链接到它的动态链接库。

在该段落中,我强调了加粗部分。 目标计算机是全新的,除.NET 4.0之外没有加载任何程序。 一旦我安装了C ++,它就能够完成对SQLite的命令。 这应该是最常见问题之一并且是先决条件的一部分,但它被埋没在第11条。 我的开发计算机已经加载了它,因为它带有Visual Studio,所以它可以在那里工作。

下载:
Visual Studio 2015的Visual C++可再发行组件:
https://www.microsoft.com/zh-cn/download/details.aspx?id=48145

更新3 (累积更新):
https://www.microsoft.com/zh-cn/download/details.aspx?id=53587


5
即使这篇文章有些过时,我也想分享我在这里找到的解决方案:http://system.data.sqlite.org/index.html/info/54e52d4c6f 如果您不想阅读所有问题,解决方案是将“msvcr100.dll”文件(可以在Windows\System32目录中找到)复制到与SQLite.Interop.dll相同的路径中。
我建议您阅读此问题以了解原因,并将文件包含在安装程序中,但仅在出现错误时安装它。我将其作为可选组件放置在设置选项中。
希望对你有所帮助, Formentz

1
非常感谢您,我尝试了所有其他方法,而这正是解决方案。 - David Benko
谢谢。这个解决方案修复了我的问题。 - Murat Özbayraktar

5
我遇到了相同的问题,请按照以下步骤操作:
  1. 确保您已经安装了SQLite Development Team提供的System.Data.SQLite.Core软件包,可以通过NuGet进行安装。
  2. 进入项目解决方案并尝试在packages文件夹内查找build文件夹。
  3. 检查您的项目框架并选择所需的SQLite.Interop.dll文件,将其放置在您的调试/发布文件夹中。

参考资料


谢谢,我使用的是不同版本的 .net 框架。参考视频很有帮助。 - Salman

5
根据 SQLite wiki 的说法,你的应用程序部署必须如下所示: Application deployment 因此,您需要遵循规则。找到与您的目标平台匹配的 dll 并将其放在图片中描述的位置。Dlls 可以在 YourSolution/packages/System.Data.SQLite.Core.%version%/ 中找到。
我在应用程序部署时遇到了问题,所以我只需在项目中添加正确的 SQLite.Interop.dll,并将 x86 文件夹添加到安装项目中的 AppplicationFolder,然后添加文件引用到 dll 即可。

4

将“SQLite.Interop.dll”文件复制到调试文件夹中的x86和x64文件夹中。这些文件应该复制到调试文件夹中的“x86”和“x64”文件夹中。


3

我已经开始使用Costura.Fody来打包(.net)程序集,并嵌入和预加载本地dll。这也有助于以后的分发,因为你可以发送一个文件。

  1. Install Costura Fody from Nuget.

  2. In your C# project create a folder called costrua32. In there add any native dlls you which C# to load.

  3. Once you have added them to this folder. Click on the properties window and change build action to "Embedded Resource"

  4. Finally you need to amend the XML file called FodyWeavers.xml as follows. Here I am specifying load the sql dll first. (note you drop the .dll)

    Weavers
     Costura
      PreloadOrder
       SQLite.Interop
       tbb_debug
       tbb
      /PreloadOrder>
     /Costura
    /Weavers
    
这样做的好处是您不需要编写任何预建或后建事件,并且最终产品完全封装成一个更大的文件。

文件夹名称应为costura32,文档请参见https://github.com/Fody/Costura#native-libraries-and-preloadorder。 - Elton Saunders

3

同时将dll添加到测试项目中(通过Nuget管理器),这样就解决了问题。


3
如果你下载了正确的二进制文件,就可以将SQLite.Interop.dll复制到你的Release或Debug文件夹中,具体根据你的项目构建选项而定。请点击此处下载正确的二进制文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接