无法加载 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个回答

160

我知道我来晚了,但是在我拉下最新的x86/x64版本(版本1.0.88.0)后就遇到了这个问题。我的本地IIS在VS2012中默认运行32位,没有简单的方法切换到x64。我的生产服务器运行64位。

无论如何,我将NuGet包安装到DLL项目中,然后我得到了这个错误。我必须也将其安装到主站点项目中才能让它工作。即使它根本不涉及SQLite类。

我猜测SQLite使用入口程序集来检测加载哪个版本的Interop。


14
在我将SQLite Core通过NuGet添加到主项目的引用后,它适用于我。 - Luca Cremonesi
将sqllite.core添加到我的WPF解决方案的主项目中对我起作用了。 - Dipu Raj
这应该是答案。 - Bobby Turkalino
4
“主站”项目是什么意思?在我的情况下,我正在进行桌面工作。你是指“创业公司”项目吗? - StayOnTarget
1
嗯,你说的对,这并不是理想的情况。我尝试从后置构建事件中复制interop dll,但它甚至都无法工作。这些dll似乎出现在后置构建事件被调用之后的x86/x64中..有点无用。 - DarkUrse
显示剩余6条评论

91

我遇到了一个问题,因为我使用的dll依赖于Sqlite(通过NuGet配置只有Sqlite核心包)。该项目编译并复制所有Sqlite dll,除了“SQLite.Interop.dll”(x86和x64文件夹都没有)。

解决方案非常简单:只需向您正在构建/运行的项目添加System.Data.SQLite.Core包作为依赖项(使用NuGet),dll将被复制。


2
尝试了这里发布的很多解决方案,这个实际上是最好的。 - Batman
2
你怎么添加这样的依赖项?我从来没有做过(VS2013) - jpgrassi
7
前往“工具”->“NuGet程序包管理器”->“管理解决方案的NuGet程序包”->“在线”->“全部”。然后搜索sqlite并添加System.Data.SQLite Core(x86/x64)。 - Marin
1
你是不是想说"System.Data.SQLite.Core"?我没有看到叫做"Sqlite.Core"的包。谢谢。 - StayOnTarget
3
我认为SQLite核心已安装,但仍然无法运行。 - KansaiRobot
显示剩余6条评论

90
所以,在添加NuGet后,部署没有复制下Interops。你可以将以下内容添加到您的csproj文件中,这应该可以修复此问题:
 <PropertyGroup> 
    <ContentSQLiteInteropFiles>true</ContentSQLiteInteropFiles>
    <CopySQLiteInteropFiles>false</CopySQLiteInteropFiles>
    <CleanSQLiteInteropFiles>false</CleanSQLiteInteropFiles>
    <CollectSQLiteInteropFiles>false</CollectSQLiteInteropFiles>
 </PropertyGroup>

如果您查看NuGet for SQLite的源代码,您可以看到它们具体是在做什么。这使我得以让ASP.Net Core成功部署。


14
ContentSQLiteInteropFiles 是答案。大多数热门答案都是猜测。 - Corey Alix
7
是的,ContentSQLiteInteropFiles就是答案。
  1. 这应该被接受为答案。
  2. 另一方面,需要调查如何将其作为NuGet包自动化工作,或者至少记录需要进行此配置的内容。
- gerleim
应该是被接受的答案。非常简单。1. 卸载项目 2. 将上述内容添加到 csproj 文件中 3. 重新加载项目。就这么简单... - BillRuhl
2
请注意,此解决方案仅适用于“旧”风格的项目。对于适用于“新”风格项目的答案,请参见 https://dev59.com/mGcs5IYBdhLWcg3wOBbl#60176344。 - MajorRefactoring
1
如何得出这样的解决方案?是否有关于添加此代码确切作用的文档?非常感谢更多信息。 - tutiplain
它似乎可以工作,但我仍然在运行时遇到故障。手动将SQLite.Interop.dll复制到Debug/Release目录是我唯一有效的方法。 - tekHedd

50
我曾在一个目标平台为Any CPU的WPF项目中使用SQLite时遇到了同样的问题。我通过以下步骤解决了这个问题:
  1. 在Visual Studio中打开项目设计器,如何操作可以在这里找到。
  2. 点击“生成”选项卡。
  3. 禁用prefer 32-bit选项。

或者,你可以将平台目标设置为x86x64。我认为这个问题是由于System.Data.SQLite库使用平台目标来获取“SQLite.Interop.dll”文件的位置所导致的。

更新:

如果无法访问项目设计器,则只需从文本编辑器中打开项目(*.csproj)文件,并将值<Prefer32Bit>false</Prefer32Bit>添加到<PropertyGroup>...</PropertyGroup>标记中。

示例代码

<PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>[Set by Visual Studio]</ProjectGuid>
    <OutputType>Exe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>[Set by Visual Studio]</RootNamespace>
    <AssemblyName>[Set by Visual Studio]</AssemblyName>
    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
    <FileAlignment>[Set by Visual Studio]</FileAlignment>
    <!--Add the line below to your project file. Leave everything else untouched-->
    <Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>

我正在使用VS 2010,没有这样的选项。 - xll
默认情况下未选中该选项,但勾选然后取消勾选即可解决问题! - Pete Kirkham
10
在我的VS2012中,这个选项是灰色的。 - Kugel
7
这个选项仅在EXE项目上可用,但我认为我们大多数人在单元测试项目中也存在这个问题。 - Brannon
1
在我的VS Pro 2015 WPF项目中,该选项对我而言是灰色的。.csproj文件已经将其设置为false,但仍然存在错误。 - vapcguy
显示剩余2条评论

35

这是我在我的项目中修复它的方法。

它一直能够工作,但当同事提交了他的更改后,我收到了“无法加载DLL 'SQLite.Interop.dll'”异常。

将项目的.csproj文件进行对比,发现这个错误存在于非工作版本中:


<ItemGroup>
     <Content Include="x64\SQLite.Interop.dll" />
     <Content Include="x86\SQLite.Interop.dll" />
</ItemGroup>

这是可工作版本的内容:

<ItemGroup>
     <Content Include="x64\SQLite.Interop.dll">
          <CopyToOutputDirectory>Always</CopyToOutputDirectory>
      </Content>
      <Content Include="x86\SQLite.Interop.dll">
          <CopyToOutputDirectory>Always</CopyToOutputDirectory>
      </Content>
</ItemGroup>

回退后,我没有收到异常。DLL文件被转储到适当的Debug\x64(等等)文件夹中。


项目的.csproj文件中没有“SQLite.Interop.dll”的<itemgroup>。我尝试添加您的解决方案,但仍然无法工作:( - aru
这在VS2012中不起作用,元素不存在。 - htm11h
非常感谢。在2015年的工作与现在相比有何不同。 - Jevgenij Kononov
2
我尝试使用基于构建类型的<copy>,但对于单元测试来说它并不起作用。OutDir 不正确。通过复制 "x86" 和 "x64" 文件夹,我猜测 sqlite(或者可能是 .net)找到了它所需的内容。非常感谢! - Corey Alix

27

当你遇到这种情况时,请尝试执行Rebuild-All操作。如果这可以解决问题,那么你可能也遇到了我曾经遇到的同样问题。

一些背景信息(我的理解):

  • SQLite有一个托管程序集(System.Data.SQLite.dll)和几个特定平台的程序集(SQLite.Interop.dll)。当通过Nuget安装SQLite时,Nuget会将特定平台的程序集添加到您的项目中(在几个文件夹中:\x86,\x64),并将这些dll配置为“始终复制”。

  • 在加载时,托管程序集将搜索\x86和\x64文件夹内的特定平台程序集。您可以在此处查看更多信息here。异常是该托管程序集尝试在这些文件夹中查找相关(SQLite.Interop.dll)(并失败)。

我的场景:

我有2个项目在我的解决方案中; 一个WPF应用程序和一个类库。WPF应用程序引用类库,类库引用通过Nuget安装的SQLite。

对我而言,问题在于当我仅修改WPF应用程序时,VS尝试执行部分重建(意识到依赖的dll未更改)。在这个过程中,VS会清理\x86和\x64文件夹的内容(删除SQLite.Interop.dll)。当我执行完整的Rebuild-All操作时,VS会正确地复制文件夹及其内容。

我的解决方案:

为了解决这个问题,我最终添加了一个Post-Build进程,使用xcopy强制将类库中的\x86和\x64文件夹复制到我的WPF项目\bin目录中。

或者,您可以使用构建配置/输出目录进行更高级的操作。


1
我收到的消息告诉我那些文件丢失了,但我以为这是权限问题。看到你的消息后,我意识到它们实际上从未在部署时传输到服务器。 - Stradas
1
我的解决方案与此几乎相同,即在启动项目中添加x86和x64文件夹,然后在各自的文件夹中添加x86互操作和x64互操作文件。我将文件的选项设置为“内容”和“始终构建”。这是我能够让我的Windows Forms应用程序在使用ClickOnce部署到其他PC时连接到嵌入式s3db数据库文件的唯一方法。令人沮丧的是,在我的PC上开发和测试应用程序时,我没有SQLite错误。 - David Alan Condit
仍然发生在VS 2017中:'( - wmebane
1
这是帮助我理解问题的答案,尽管我的修复方法有些不同。我的问题是手动添加了system.data.Sqlite.dll。这样Sqlite.Interop.dll就不会自动复制到\x86和x64中。解决方法是删除引用,然后通过Nuget重新添加它。 - Susan Wang

19

我在运行Visual Studio Express 2013时遇到了相同的问题。我尝试了这里和其他地方提到的几种解决方法,但都没有成功。我希望这个解决方法对其他人有所帮助。

我通过在测试SQLite服务的测试类上使用DeploymentItem属性来修复它。

例如:

[TestClass]
[DeploymentItem(@"x86\SQLite.Interop.dll", "x86")] // this is the key
public class LocalStoreServiceTests
{

    [TestMethod]
    public void SomeTestThatWasFailing_DueToThisVeryIssue()
    {
         // ... test code here
    }
}

这会导致所需的 SQLite.Interop.dll 被复制到相应的“TestResults”文件夹内的 x86 目录中。

一切都是绿色的。一切都很好。


1
这个解决方案只在使用Microsoft.VisualStudio.TestTools.UnitTesting命名空间时有效。 - sapbucket
4
如果您正在使用MSTest,则这是一个正确的解决方案。 SQLite表现正常,没有任何问题地找到了SQLite.Interop.dll,直到我在测试中使用DeploymentItem("some.csv")。以这种方式包含.csv文件会触发MSTest将所有引用的dll复制到TestResults目录中。由于SQLite.Interop.dll不在项目中被引用(也无法引用,因为它是非托管代码),它从未被复制过去。 - Johann
你最好添加两行代码,每个架构一行。这样可以保护你,以防测试运行程序恰好在64位上运行。 - Kirk Woll

18

通过从 工具 -> 扩展和更新 更新NuGet,然后使用命令 PM> Update-Package -reinstall System.Data.SQLite.Core 重新安装SQLite.Core解决了我的问题。


如果在执行此操作时出现错误,尝试移除我的SQLite DLL/引用,并从NuGet完全重新安装它们,这对我很有帮助。 - KayakinKoder
重新安装SQLite核心对我也有帮助。这个问题发生在VS2012中。VS没有将x62版本包含到Web部署包中。 - Andrey Ravkov
在我的VS2015专业版中也已经修复了。 - Rahul Kishore

17

旧项目文件格式

即以以下内容开头的项目文件:<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

在您的“主”/根项目的csproj文件中添加以下内容

<PropertyGroup> 
    <ContentSQLiteInteropFiles>true</ContentSQLiteInteropFiles>
    <CopySQLiteInteropFiles>false</CopySQLiteInteropFiles>
    <CleanSQLiteInteropFiles>false</CleanSQLiteInteropFiles>
    <CollectSQLiteInteropFiles>false</CollectSQLiteInteropFiles>
</PropertyGroup>

新的SDK项目文件格式

即以<Project Sdk="Microsoft.NET.Sdk.*">开头的项目

在依赖链中每个ProjectReference/PackageImport中添加PrivateAssets="none",直到System.Data.Sqlite PackageImport为止

例如:

<PackageReference Include="System.Data.SQLite.Core" Version="1.0.110" PrivateAssets="none"/>

成功输出显示: 从“..\packages\System.Data.SQLite.Core.1.0.105.2\build\net451\x64\SQLite.Interop.dll”复制文件到“XXProject\release\x64\SQLite.Interop.dll”。 从“..\packages\System.Data.SQLite.Core.1.0.105.2\build\net451\x86\SQLite.Interop.dll”复制文件到“XXProject\release\x86\SQLite.Interop.dll”。 - John Jang
请使用此解决方案,永远不要仅手动复制DLL文件! - John Jang

10

我在多个项目的解决方案中遇到了类似的问题。SQLite.Interop.dll是软件中使用ClickOnce分发的一个插件所必需的。

在Visual Studio中进行调试时一切正常,但是部署版本缺少包含该DLL文件的x86/和x64/文件夹。

解决方法是,在解决方案的启动项目(也是要发布的项目)中创建这两个子文件夹,将DLL文件复制到其中,并将它们设置为“始终复制内容”(Content Copy Always)。

这样,ClickOnce发布工具就会自动将这些文件和文件夹包含在清单中,并将软件与其一起部署。


1
这是唯一对我有效的解决方案...而且..当你的应用程序在用户的电脑上突然关闭时,调试真是一件痛苦的事情。 - stoic

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