System.Data.SQLite от NuGet, interop dll не копируется в выходной каталог
Я установил System.Data.SQLite Core (x86/x64) из NuGet. Он был создан без предупреждений, но бросил System.DllNotFoundException
отношении SQLite.Interop.dll
. Я сфальсифицировал свои проекты, чтобы скопировать SQLite.Interop.dll
из каталога пакетов NuGet в выходной каталог, и теперь он запускается без исключения.
Почему пакет NuGet не сконфигурировал мои проекты для размещения соответствующей DLL-оболочки в выходном каталоге? Похоже, он должен это сделать.
Я новичок в interop, и я унаследовал эту базу кода, которая ранее ссылалась на System.Data.SQLite.dll
прямо по пути. Я переключился на NuGet, чтобы избавиться от предупреждений о несоответствии между архитектурой процессора проекта и System.Data.SQLite
. Я пытаюсь построить все проекты как AnyCPU.
Ответы
Ответ 1
Я думал, что это происходит, когда я копировал файлы из моей выходной папки в другое место, когда я их развернул. Я пропустил тот факт, что файлы взаимодействия были скопированы, но они скопированы в папки x64 и x86 в вашей выходной папке.
Если вы запустите msbuild в отладке проекта, вы можете найти ссылки на цель CopySQLiteInteropFiles
чтобы убедиться, что она запущена.
Ответ 2
В моем случае проблема заключалась в том, что я использовал SQLite внутри проекта библиотеки классов, который затем использовался другим проектом WPF (gui type).
Решено, что SQL.Interop.dll не будет скопирован в выходной каталог, используя следующую команду Post-Build, внутри Project Properties → Build Events:
xcopy "$(SolutionDir)packages\System.Data.SQLite.Core.1.0.101.0\build\net451\x86\SQLite.Interop.dll" "$(OutputDir)" /y /f
/y overwrites
/f displays actual filenames being copied
Ответ 3
В моем случае SQL.Interop.dll никак не копировался Nuget, вручную помещал правильную версию dll в папку x86 и x64, решив проблему.
Если вы установили Sqlite из Nuget, вы можете найти SQL.Interop.dll в этой папке (для.NET 4.0)
PROJECT_FOLDER\packages\System.Data.SQLite.Core.1.0.*.*\build\net40
Ответ 4
Скопируйте это в файл проекта:
<PropertyGroup>
<ContentSQLiteInteropFiles>true</ContentSQLiteInteropFiles>
<CopySQLiteInteropFiles>false</CopySQLiteInteropFiles>
<CleanSQLiteInteropFiles>false</CleanSQLiteInteropFiles>
<CollectSQLiteInteropFiles>false</CollectSQLiteInteropFiles>
</PropertyGroup>
Источник: файлы SQLite.Interop.dll не копируют путь к проекту, если требуется по ссылке
Ответ 5
С пакетом System.Data.SQLite.Core
NuGet версии 1.0.104 у меня была та же проблема, что и @Eternal21 и @Patrick. То есть проект A ссылается на ссылки SQLite и B проекта A, где SQlite.Interop.dll
не копируется в выходной каталог B.
Я нашел решение, которое решает проблему в проекте A, а не в B, что является более надежным решением, поскольку оно устраняет проблему один раз для всех будущих проектов, относящихся к A. Файл .targets
пакета NuGet содержит следующий раздел:
<ItemGroup Condition="'$(ContentSQLiteInteropFiles)' != '' And
'$(ContentSQLiteInteropFiles)' != 'false' And
'@(SQLiteInteropFiles)' != ''">
<Content Include="@(SQLiteInteropFiles)">
<Link>%(RecursiveDir)%(FileName)%(Extension)</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
В этом разделе SQLite.Interop.dll
добавляется как ссылка, которая должна быть скопирована для вывода проекта A, а также для вывода ссылочных проектов (например, B). Но свойство MSBuild ContentSQLiteInteropFiles
по умолчанию не определено (я не знаю, почему), отключив ссылку по первому условию. Чтобы включить его, я добавил следующую строку в элемент PropertyGroup
проектов A .csproj
file:
<ContentSQLiteInteropFiles>true</ContentSQLiteInteropFiles>
Обратите внимание, что эта строка должна предварительно использовать элемент Import
для файла .targets
пакета NuGet.
Ответ 6
В моем случае у файла myProject.csproj
не было определено значение параметра System.Data.SQLite.Core.targets
. Я добавил следующую строку и обе версии SQLite.Interop.dll
для x64
и x86
теперь скопированы для всех целей сборки.
<Import Project="..\packages\System.Data.SQLite.Core.1.0.98.1\build\net45\System.Data.SQLite.Core.targets" Condition="Exists('..\packages\System.Data.SQLite.Core.1.0.98.1\build\net45\System.Data.SQLite.Core.targets')" />
Я не уверен, что произойдет, когда пакет NuGet для System.Data.SQLite.Core
будет обновлен, и если путь пакета необходимо будет изменить вручную.
Ответ 7
в моем случае с использованием NuGet для установки SQLite, и все же мне нужно добавить вручную SQliteinterop.dll в качестве ресурса. Затем я строю muy proyect, и когда я публикую его, он отлично работает. (Работа с конфигурацией x86)
Ответ 8
Ни один из вышеперечисленных ответов, похоже, не работал для меня, возможно, потому, что я на VS2015, но это поразило меня как повод добавить мое собственное решение этой проблемы.
Моя конкретная ситуация такая же, как у @Eternal21. У меня есть пользовательский интерфейс WPF, который использует клиентскую библиотеку, которая имеет SQLite, добавленную к ней через nuget. И, да, проблема заключалась в том, что Interop.dll не был скопирован в приложение запуска (то есть интерфейс WPF, который не имеет установленного SQLite).
Решение простого добавления SQLite в проект WPF с использованием nuget является быстрым и легким решением, если вы спешите.
Мое немного тяжелое решение использует XCOPY, но имеет преимущество в копировании как x86, так и x64-каталогов, а также справляется с сборками Debug и Release. Его недостатком является то, что он содержит жестко запрограммированные названия проектов. Я могу видеть, как можно использовать макрос, чтобы избавиться от первого, но я не мог легко понять, как избавиться от второго, поэтому вам придется вручную его менять, если имя проекта изменилось (но это довольно редко).
Мое решение заключается в использовании этих команд XCOPY в пост-сборке проекта запуска:
xcopy $(SolutionDir)DALProject\bin\$(ConfigurationName)\x64\SQLite.Interop.dll $(SolutionDir)WPFProject\bin\$(ConfigurationName)\x64\*.* /C /F /S /E /Y
xcopy $(SolutionDir)DALProject\bin\$(ConfigurationName)\x86\SQLite.Interop.dll $(SolutionDir)WPFProject\bin\$(ConfigurationName)\x86\*.* /C /F /S /E /Y
/C - Продолжает копирование, даже если ошибка (возможно, это не требуется).
/F - Отображает полные пути копируемых файлов (может быть опущен для очистки сборки).
/S - копирует подкаталоги (это был единственный способ получить его для создания папок /x86 и /x64).
/E - копирует каталоги и подкаталоги (возможно, дубликаты /S).
/Y - подавляет запрос, если файл назначения уже существует.
Я установил, что это работает только при успешной сборке, и это работает для меня. Надеюсь, это поможет кому-то.
Ответ 9
У меня есть проект DLL, который использует пакет SQLite от nuget, но тестовый проект для него всегда будет поднимать исключение DLL, не найденное.
Самое простое решение, которое я нашел, это добавить пакет SQLite nuget в тестовый проект.