System.Data.SQLite from NuGet, interop dll not copied to output directory

北城以北 提交于 2020-01-29 10:21:52

问题


I installed System.Data.SQLite Core (x86/x64) from NuGet. It built without warnings but threw System.DllNotFoundException regarding SQLite.Interop.dll. I rigged my projects to copy the SQLite.Interop.dll from under the NuGet package's directory to the output directory, and now it runs without the exception.

Why didn't the NuGet package configure my projects to put the appropriate interop dll in the output directory? It seems like it should be able to do that.

I'm new to interop and I inherited this codebase, which previously referenced System.Data.SQLite.dll directly by path. I switched to NuGet to get rid of warnings about a mismatch between the processor architecture of the project vs System.Data.SQLite. I'm trying to build all projects as AnyCPU.


回答1:


I thought this was happening to, as I was copying the files from my output folder to another location when I deployed them. I missed the fact that the interop files WERE being copied, but they are copied to x64 and x86 folders within your output folder.

If you run msbuild in debug on the project, you can look for references to the CopySQLiteInteropFiles target to ensure that it is running.




回答2:


Copy this to your project file:

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

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




回答3:


In my case, the problem was the fact that I was using SQLite inside a class library project that was then used by another WPF (gui type) project.

Solved the SQL.Interop.dll not getting copied to output directory, by using the following Post-Build command, inside 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



回答4:


In my case the SQL.Interop.dll was not copied by Nuget in any way, manually put the right version of the dll in the x86 and x64 folder solved the issue.

If you've installed Sqlite from Nuget, you can find the SQL.Interop.dll in this folder (for .NET 4.0)

PROJECT_FOLDER\packages\System.Data.SQLite.Core.1.0.*.*\build\net40




回答5:


With the System.Data.SQLite.Core NuGet package version 1.0.104, I had the same problem as @Eternal21 and @Patrick. That is, project A references SQLite and project B references A where SQlite.Interop.dll is not copied into the output directory of B.

I found a solution that solves the trouble in project A rather than B which is a more robust solution since it fixes the problem once for all future projects refering to A. The .targets file of the NuGet package contains the following section:

<ItemGroup Condition="'$(ContentSQLiteInteropFiles)' != '' And
                      '$(ContentSQLiteInteropFiles)' != 'false' And
                      '@(SQLiteInteropFiles)' != ''">
  <Content Include="@(SQLiteInteropFiles)">
    <Link>%(RecursiveDir)%(FileName)%(Extension)</Link>
    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
  </Content>
</ItemGroup>

This section adds SQLite.Interop.dll as a reference that has to be copied to project A's output and also to the output of refering projects (like B). But the MSBuild property ContentSQLiteInteropFiles is undefined by default (I don't know why) disabling the reference by the first condition. To enable it, I added the following line to a PropertyGroup element of projects A's .csproj file:

<ContentSQLiteInteropFiles>true</ContentSQLiteInteropFiles>

Please note that this line must prececde the Import element for the .targets file of the NuGet package.




回答6:


In my case the myProject.csproj file did not have the System.Data.SQLite.Core.targets defined. I added the following line and both x64 and x86 versions of SQLite.Interop.dll are now copied for all build targets.

<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')" />

I'm not sure what will happen when the NuGet package for System.Data.SQLite.Core gets updated and if the package path will need to be manually altered.




回答7:


in my case using NuGet for installing SQLite and still I need to add manually SQliteinterop.dll as a Resource. Then I build muy proyect and when I publish it works fine. (Working with x86 configuration)




回答8:


None of the answers above seemed to work for me, perhaps because I am on VS2015, but that struck me as a good reason to add my own solution to this problem.

My specific situation is the same as @Eternal21 - I have a WPF UI consuming a client library which is the one that has SQLite added to it via nuget. And, yes, the problem was that the Interop.dll was not copied to the startup application (i.e the WPF UI that does not have SQLite installed).

The solution of simply adding SQLite to the WPF project using nuget is a quick and easy fix if you are in a hurry.

My slightly heavy-handed solution uses XCOPY but does have the advantage of copying both the x86 and the x64 directories and also copes with Debug and Release builds. Its downside is that it contains hard-coded project names. I can see how you could use a macro to get rid of the first one but I couldn't easily see how to get rid of the second, so you would have to change it manually if the project name changed (but this is fairly rare).

My solution is to use these XCOPY commands in the post-build of the startup project:

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 - Continues copying even if error (maybe this is not needed).

/F - Displays full paths of files being copied (could be omitted to clean-up build output).

/S - Copies subdirectories (which was the only way I could get it to create the /x86 and /x64 folders).

/E - Copies directories and subdirectories (maybe duplicates /S).

/Y - Suppresses prompt if destination file already exists.

I set this to run only on successful build and it works a treat for me. Hope it helps someone.




回答9:


I have a DLL project that uses the SQLite package from nuget but a test project for it would always raise the DLL not found exception.

The simplest solution I found was to add the SQLite nuget package to the test project too.




回答10:


I added

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

In the csproj of the project that references the nuget package. This part needs to be above the 'Import' of the 'System.Data.SQLite.Core.targets'.

Then, added the following to the csproj-file, so that the x64-version of the 'SQLite.Interop.dll' is placed in the bin folder.

    <ItemGroup>
        <Content Include="..\packages\System.Data.SQLite.Core.1.0.111.0\build\net46\x64\SQLite.Interop.dll">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </Content>
    </ItemGroup>

Although this statement needs to be changed when the nuget package is updated.



来源:https://stackoverflow.com/questions/26768005/system-data-sqlite-from-nuget-interop-dll-not-copied-to-output-directory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!