System.DllNotFoundException на моно SQLite

Я пытался понять это в последнее время. Он работает на моей машине с Windows, где я получил SQLite от NuGet, но...

Когда я положил System.Data.SQLite.dll а также SQLite.Interop.dll прямо с моей машины Windows на сервер Linux говорит, что SQLite.Interop.dll не найден, но я уверен, что вижу его рядом с исполняемым файлом.

Затем я попытался скомпилировать System.Data.SQLite.dll с /p:UseInteropDll=false, но без удачи. На этот раз это говорит о том, что System.Data.SQLite.dll не найден.

Что это за "не найденная" тайна?

3 ответа

Решение

Использование Mono.Data.SQLite.dll в линуксе Посмотрите руководство Mono по использованию SQLite в Linux или соберите System.Data.SQLite.dll в 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>

Никаких изменений кода не требуется. Вы можете построить это самостоятельно.

  1. apt-get install build-essentials unzip
  2. Загрузите исходный код SQLITE - вам нужен полный исходный код. В настоящее время называется sqlite-netFx-full-source-1.0.104.0.zip.
  3. unzip а также cd Source,
  4. chmod +x compile-interop-assembly-release.sh построить сценарий оболочки, а затем запустить его ./compile-interop-assembly-release.sh, - Это будет строить .so файл в ../bin каталог.
  5. Скопируйте это .so файл в каталог, в котором находится ваше приложение
  6. Запустите ваше приложение как обычно.
  7. Примечание. Убедитесь, что база данных SQLite и каталог, в котором она находится, доступны для записи пользователю, от имени которого вы пытаетесь запустить.

Я начал разработку в 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

После копирования всех сгенерированных файлов в каталог bin проекта Mono все заработало.

Версия исходного кода поставщика SQLite, которую я использовал, была 1.0.98.1.

Надеюсь, это сэкономит кому-то много времени...

Я пробовал все вышеперечисленные варианты, но эти варианты не смогли решить проблему с SQLite DLL. Возможно, я использую версию ubuntu 18, поэтому попробовал другой вариант и вот шаги,

1) Загрузите исходный код SQLite из https://system.data.sqlite.org/downloads/1.0.111.0/sqlite-netFx-full-source-1.0.111.0.zip

2) разархивируйте исходный код и компакт-диск, чтобы разархивировать каталог

3) Выполните следующую команду в терминале,

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

4) Вышеупомянутая команда создаст файл dll по следующему пути,

sqlite-netFx-полный-источник-1.0.111.0 / bin / 2010 / ReleaseMonoOnPosix / bin

5) Скопируйте System.Data.SQLite.dll в папку bin вашего проекта.

6) Очистить проект и построить заново.

Надеюсь, это поможет.

Начиная с https://www.nuget.org/packages/System.Data.SQLite.Core/ 1.0.109 вам не нужно ничего компилировать самостоятельно, так как роднойSQLite.Interop.dllфайлы включены в пакет NuGet для всех платформ (Linux, macOS и Windows). Обратите внимание, что хотяdllРасширение используется для всех платформ, файлы на самом деле являются собственными динамическими библиотеками (обычно с суффиксом dylib в macOS и так далее в Linux).

$ 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.

Но можно автоматически скопировать SQLite.Interop.dllфайл в выходной каталог в Linux и macOS. ДобавитьFixSQLiteInteropFilesOnLinuxAndOSX target (описанный ниже) в вашем файле csproj, и вы сможете использовать System.Data.SQLite.Core в Linux и macOS в моно без DllNotFoundException. Вот как должен выглядеть ваш проект:

<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 свойство подлежит определению.

Другие вопросы по тегам