Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLite.Interop.dll files does not copy to project output path when required by referenced project

I am using the System.Data.SQLite Core Version: 1.0.98.1 nuget package with Visual Studio 2015. When I build my project that references my System.Data.SQLite package, it copies two folders (x86 and x64) each containing a SQLite.Interop.dll to the output directory. However when I build my test project or any other project that references the previously mentioned project, these folders do not get copied to the the parent project's output directory, and I get a DllNotFoundException on the SQLite.Interop.dll.

Note: this is specifically when the project referencing System.Data.SQLite is referenced by another project

like image 220
BenCamps Avatar asked Sep 17 '15 20:09

BenCamps


2 Answers

The recomended solution as doumented here is to create a System.Data.SQLite.Core.targets.user in your packages\System.Data.SQLite.Core.1.0.98.1\build\[your framework version here] folder containing

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup> 
        <ContentSQLiteInteropFiles>true</ContentSQLiteInteropFiles>
        <CopySQLiteInteropFiles>false</CopySQLiteInteropFiles>
        <CleanSQLiteInteropFiles>false</CleanSQLiteInteropFiles>
        <CollectSQLiteInteropFiles>false</CollectSQLiteInteropFiles>
    </PropertyGroup>
</Project>

But if you don't want to add anything in your packages folder to your source control, you can just add the following directly to your project file

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

Update for SDK style projects

In the new SDK project style, there is a change in how dependencies are resolved across nested projects and packages. In the build process, assets are resolved and a obj\project.assets.json file is generated listing the assets from all the various dependencies. The project assets file is then used to determine what targets need to be imported and what files need to be copied to the output directory. There is, however a difference in how assets are included from non-direct dependencies. Target files from the build folder of non-direct dependencies are not imported. The old workaround depends on System.Data.SQLite.Core.targets getting imported into the parent project. Projects that directly depend on System.Data.Sqlite can override this behavior by adding PrivateAssets="none" to the PackageImport. You will also need to add this to each PackageImport or ProjectReference` in your dependency chain. However, you won't need to combine this with the prior workaround.

TLDR

In the project that directly references System.Data.Sqlite add PrivateAssets="none" to your PackageImport

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

For each project in your dependency chain up to your root project also addPrivateAssets="none"

<ProjectReference Include="..\MyProject.csproj" PrivateAssets="none"/>
like image 53
BenCamps Avatar answered Oct 23 '22 12:10

BenCamps


<ContentSQLiteInteropFiles>true</ContentSQLiteInteropFiles> seems to have no effect with .NET Standard 2.0 where SQLite.interop.dll is still not recognized as content nor dependency in a referencing project.

I hope someone find a cleaner solution for this...

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard20</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="System.Data.SQLite.Core" Version="1.0.112" GeneratePathProperty="true" />
  </ItemGroup>

  <ItemGroup>
    <!-- Fix to get SQLite.interop.dll copied when using netstandard -->
    <Content Include="$(PkgSystem_Data_SQLite_Core)\runtimes\win-x86\native\netstandard2.0\SQLite.Interop.dll" Link="x86\SQLite.Interop.dll">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
    <Content Include="$(PkgSystem_Data_SQLite_Core)\runtimes\win-x64\native\netstandard2.0\SQLite.Interop.dll" Link="x64\SQLite.Interop.dll">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
  </ItemGroup>

</Project>
like image 3
Michel Jansson Avatar answered Oct 23 '22 13:10

Michel Jansson