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