【问题标题】:System.DllNotFoundException on Mono SQLiteMono SQLite 上的 System.DllNotFoundException
【发布时间】:2014-02-13 02:40:43
【问题描述】:

我最近一直在尝试解决这个问题。它在我的 Windows 机器上运行,我从 NuGet 获得 SQLite,但是......

当我将System.Data.SQLite.dllSQLite.Interop.dll 直接从我的Windows 机器放入Linux 服务器时,它说SQLite.Interop.dll 没有找到,但我确信我可以看到它的下一个可执行文件。

然后我尝试用/p:UseInteropDll=false 编译System.Data.SQLite.dll,但没有运气。这次它说找不到System.Data.SQLite.dll

这个“未发现”的谜团是什么?

【问题讨论】:

  • 里乐 user3791372 说,原来你需要在 Linux 下构建 System.Data.SQLite,因为没有预构建的二进制文件可供下载 - 你可以在这篇文章中找到详细说明:blog.wezeku.com/2016/10/09/…

标签: c# sqlite mono dllnotfoundexception


【解决方案1】:

System.Data.SQLite.Core 1.0.109 开始,您不需要自己编译任何东西,因为原生SQLite.Interop.dll 文件包含在适用于所有平台(Linux、macOS 和 Windows)的 NuGet 包中。请注意,虽然dll 扩展名用于所有平台,但这些文件实际上是原生动态库(在 macOS 上通常后缀为 dylib,在 Linux 上通常后缀为 so)。

$ find ~/.nuget/packages/system.data.sqlite.core/1.0.111/runtimes -name SQLite.Interop.dll -print0 | xargs -0 file
…/runtimes/linux-x64/native/netstandard2.0/SQLite.Interop.dll: ELF 64-bit LSB pie executable x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=96ce4120b31bad7d95f7b9ccf7c4bbb7717ae0b1, with debug_info, not stripped
…/runtimes/osx-x64/native/netstandard2.0/SQLite.Interop.dll:   Mach-O 64-bit dynamically linked shared library x86_64
…/runtimes/win-x86/native/netstandard2.0/SQLite.Interop.dll:   PE32 executable (DLL) (GUI) Intel 80386, for MS Windows
…/runtimes/win-x64/native/netstandard2.0/SQLite.Interop.dll:   PE32+ executable (DLL) (GUI) x86-64, for MS Windows

不幸的是,负责将本机动态库复制到输出目录的 MSBuild 目标仅适用于 Windows。这可能是因为该软件包的作者假设 .NET Framework 仅在 Windows 上运行,这要归功于 Mono。另外,如果你想看看,CopySQLiteInteropFiles 目标可以在~/.nuget/packages/system.data.sqlite.core/{version}/build/net4*/System.Data.SQLite.Core.targets 中找到。

但在 Linux 和 macOS 上可以自动将 SQLite.Interop.dll 文件复制到输出目录中。在您的 csproj 文件中添加 FixSQLiteInteropFilesOnLinuxAndOSX 目标(如下所述),您将能够在没有 DllNotFoundException 的情况下在运行单声道的 Linux 和 macOS 上使用 System.Data.SQLite.Core。你的项目应该是这样的:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net452</TargetFramework>
  </PropertyGroup>
  <Target Name="FixSQLiteInteropFilesOnLinuxAndOSX" BeforeTargets="CopySQLiteInteropFiles">
    <ItemGroup>
      <SQLiteInteropFiles Condition="$([MSBuild]::IsOsPlatform(Linux)) OR $([MSBuild]::IsOsPlatform(OSX))" Remove="@(SQLiteInteropFiles)" />
      <SQLiteInteropFiles Condition="$([MSBuild]::IsOsPlatform(Linux))" Include="$(PkgSystem_Data_SQLite_Core)/runtimes/linux-x64/native/netstandard2.0/SQLite.Interop.*" />
      <SQLiteInteropFiles Condition="$([MSBuild]::IsOsPlatform(OSX))" Include="$(PkgSystem_Data_SQLite_Core)/runtimes/osx-x64/native/netstandard2.0/SQLite.Interop.*" />
    </ItemGroup>
  </Target>
  <ItemGroup>
    <PackageReference Include="System.Data.SQLite.Core" Version="1.0.111" GeneratePathProperty="true" />
  </ItemGroup>
</Project>

确保在包引用中添加GeneratePathProperty="true"。这是定义PkgSystem_Data_SQLite_Core 属性所必需的。

【讨论】:

    【解决方案2】:

    我尝试了以上所有选项,但这些选项无法解决 SQLite DLL 问题,可能是因为我使用的是 ubuntu 18 版本,所以尝试了其他选项,这里是步骤,

    1) 从https://system.data.sqlite.org/downloads/1.0.111.0/sqlite-netFx-full-source-1.0.111.0.zip下载SQLite源代码

    2) 解压源码并cd到解压目录

    3) 在终端中运行以下命令,

    xbuild /p:Configuration=Release /p:UseInteropDll=false /p:UseSqliteStandard=true ./System.Data.SQLite/System.Data.SQLite.2010.csproj

    4) 上面的命令会在以下路径创建一个 dll 文件,

    sqlite-netFx-full-source-1.0.111.0/bin/2010/ReleaseMonoOnPosix/bin

    5) 将 System.Data.SQLite.dll 复制到您的项目 bin 文件夹中。

    6) 清理项目并重新构建。

    我希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      无需更改代码。您可以自己构建它。

      1. apt-get install build-essentials unzip
      2. 下载 SQLITE 源代码 - 您需要完整的源代码。目前称为sqlite-netFx-full-source-1.0.104.0.zip
      3. unzipcd Source,
      4. chmod +x compile-interop-assembly-release.sh 构建 shell 脚本,然后运行它 ./compile-interop-assembly-release.sh。 - 它将在../bin 目录中构建一个.so 文件。
      5. 将此.so 文件复制到您的应用程序所在的目录
      6. 正常运行您的应用程序。
      7. 注意:确保您的 SQLite 数据库及其所在的目录可由您尝试运行的用户写入。

      【讨论】:

      • 好的 - 我在这里找到了答案:blog.wezeku.com/2016/10/09/…
      • 还有其他一些我们需要更改的配置设置吗?我仍然遇到同样的错误
      • 在 macOS 上,我注意到将构建的 libSQLite.Interop.dylib 文件(相当于 Linux 上的 .so 文件)复制到应用程序目录可能不起作用。相反,我将libSQLite.Interop.dylib 直接复制到/Library/Frameworks/Mono.framework/Libraries/
      • 嗨,当我这样做并尝试启动应用程序时,我得到一个:“System.EntryPointNotFoundException:无法在 DLL“sqlite3”中找到名为“sqlite3_key”的入口点”你知道为什么吗?
      【解决方案4】:

      在 Linux 上使用 Mono.Data.SQLite.dll。看看using SQLite on Linuxbuild the System.Data.SQLite.dll on Mono的Mono手册。

      你也可以映射DLL:

      <configuration>
        <dllmap dll="sqlite" target="libsqlite.so.0" os="linux"/>
        <dllmap dll="sqlite" target="libsqlite.0.dylib" os="osx"/>
        <dllmap dll="sqlite3" target="libsqlite3.so.0" os="linux"/>
        <dllmap dll="sqlite3" target="libsqlite3.0.dylib" os="osx"/>
      </configuration>
      

      【讨论】:

      • 不幸的是,当应用程序应该在 Mono 和 .NET 上运行时,这不是一个有用的解决方案。
      • 这是一种在每个平台上进行不同映射的方法,只需为每个平台部署不同的.config文件
      • @Alexandre Marcondes,我们的应用程序应该在 Mono 和 .NET 上运行。我们如何在 Ubuntu Linux 上为 Mono 和 .NET 部署不同的 .config 文件?谢谢。
      • 如何映射 DLL?你把那个sn-p放在哪里?
      【解决方案5】:

      我开始在 Windows 中进行开发,但随后将应用程序移至 Mono (Ubuntu 14),这是 SQLite 提供程序未能按照 OP 所述加载的地方。

      我不得不使用以下命令重新编译 System.Data.SQLite.dll:

      MSBuild System.Data.SQLite.2012.csproj /t:Rebuild /p:UseInteropDll=false /p:UseSqliteStandard=true 
      

      但是,在此之后,我遇到了以下异常:

      提供程序未返回 ProviderManifest 实例。 方法System.Data.SQLite.UnsafeNativeMethods:GetSettingValue (string,string)' is inaccessible from methodSystem.Data.SQLite.EF6.SQLiteProviderManifest:GetProviderManifestToken(string)'

      要解决这个问题,我必须使用以下命令重新编译 System.Data.SQLite.EF6.dll:

      MSBuild System.Data.SQLite.EF6.2012.csproj /t:Rebuild /p:UseInteropDll=false /p:UseSqliteStandard=true
      

      将所有生成的文件复制到 Mono 项目的 bin 目录后,一切正常。

      我使用的 SQLite 提供程序源代码版本是 1.0.98.1。

      希望这可以为某人节省很多时间...

      【讨论】:

      • 这对我有用。不要忘记在发布模式下使用 /p:Configuration=Release 构建。构建 EF6 对我来说不是必需的,也没有编译。首先,我尝试在服务器上编译 libSQLite.Interop.,但从未让它工作。现在它起作用了。但是,不使用互操作库有“不明确的缺点”。需要记住的一点。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-01
      • 2023-03-07
      • 2016-06-27
      • 1970-01-01
      相关资源
      最近更新 更多