【问题标题】:System.Data.SQLite from NuGet, interop dll not copied to output directory来自 NuGet 的 System.Data.SQLite,互操作 dll 未复制到输出目录
【发布时间】:2015-01-02 06:47:13
【问题描述】:

我安装了System.Data.SQLite Core (x86/x64) from NuGet。它在没有警告的情况下构建,但针对SQLite.Interop.dll 抛出了System.DllNotFoundException。我操纵我的项目将 NuGet 包目录下的 SQLite.Interop.dll 复制到输出目录,现在它可以正常运行了。

为什么 NuGet 包没有将我的项目配置为将适当的互操作 dll 放在输出目录中?看起来应该可以做到。

我是互操作的新手,我继承了这个代码库,它之前直接通过路径引用了 System.Data.SQLite.dll。我切换到 NuGet 以消除有关项目处理器架构与 System.Data.SQLite 之间不匹配的警告。我正在尝试将所有项目构建为 AnyCPU。

【问题讨论】:

    标签: c# .net visual-studio sqlite interop


    【解决方案1】:

    我加了

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

    在引用nuget包的项目的csproj中。这部分需要在'System.Data.SQLite.Core.targets'的'Import'之上。

    然后,将以下内容添加到 csproj 文件中,以便将 x64 版本的“SQLite.Interop.dll”放在 bin 文件夹中。

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

    虽然在更新nuget包时需要更改此语句。

    【讨论】:

      【解决方案2】:

      将此复制到您的项目文件中:

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

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

      【讨论】:

      • 成功了!我花了 6.5 小时才找到这个。
      【解决方案3】:

      我有一个使用 nuget 的 SQLite 包的 DLL 项目,但它的测试项目总是会引发 DLL not found 异常。

      我找到的最简单的解决方案是将 SQLite nuget 包也添加到测试项目中。

      【讨论】:

        【解决方案4】:

        使用System.Data.SQLite.Core NuGet 包版本1.0.104,我遇到了与@Eternal21 和@Patrick 相同的问题。即项目A引用SQLite,项目B引用A,其中SQlite.Interop.dll没有复制到B的输出目录中。

        我找到了解决项目 A 而不是 B 中的问题的解决方案,这是一个更强大的解决方案,因为它为所有未来引用 A 的项目解决了一次问题。NuGet 包的.targets 文件包含以下部分:

        <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 未定义(我不知道为什么)禁用第一个条件的引用。为了启用它,我将以下行添加到项目 A 的 .csproj 文件的 PropertyGroup 元素中:

        <ContentSQLiteInteropFiles>true</ContentSQLiteInteropFiles>
        

        请注意,此行必须在 NuGet 包的 .targets 文件的 Import 元素之前。

        【讨论】:

        • 谢谢!这解决了我的问题。
        【解决方案5】:

        上面的答案似乎都不适合我,可能是因为我在 VS2015 上,但这让我觉得这是一个很好的理由来添加我自己的解决方案来解决这个问题。

        我的具体情况与@Eternal21 相同——我有一个使用客户端库的 WPF UI,该客户端库是通过 nuget 添加 SQLite 的。而且,是的,问题在于 Interop.dll 没有复制到启动应用程序(即没有安装 SQLite 的 WPF UI)。

        如果您赶时间,使用 nuget 将 SQLite 简单地添加到 WPF 项目的解决方案是一种快速简便的解决方案。

        我稍微笨拙的解决方案使用 XCOPY,但确实具有复制 x86 和 x64 目录的优势,并且还可以处理调试和发布版本。它的缺点是它包含硬编码的项目名称。我可以看到如何使用宏来摆脱第一个,但我无法轻易看到如何摆脱第二个,因此如果项目名称更改,您必须手动更改它(但这相当罕见)。

        我的解决方案是在启动项目的后期构建中使用这些 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 - 如果目标文件已经存在,则禁止提示。

        我将此设置为仅在成功构建时运行,这对我来说是一种享受。希望它可以帮助某人。

        【讨论】:

          【解决方案6】:

          在我使用 NuGet 安装 SQLite 的情况下,我仍然需要手动添加 SQliteinterop.dll 作为资源。然后我建立了 muy proyect,当我发布它时它工作正常。 (使用 x86 配置)

          【讨论】:

            【解决方案7】:

            在我的例子中,问题在于我在一个类库项目中使用 SQLite,然后被另一个 WPF(gui 类型)项目使用。

            解决了 SQL.Interop.dll 没有被复制到输出目录的问题,方法是在 Project Properties -> Build Events 中使用以下 Post-Build 命令:

            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
            

            【讨论】:

              【解决方案8】:

              在我的情况下,myProject.csproj 文件没有定义 System.Data.SQLite.Core.targets。我添加了以下行,SQLite.Interop.dllx64x86 版本现在都为所有构建目标复制。

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

              我不确定当System.Data.SQLite.Core 的 NuGet 包更新时会发生什么,以及是否需要手动更改包路径。

              【讨论】:

                【解决方案9】:

                在我的情况下,Nuget 没有以任何方式复制 SQL.Interop.dll,手动将正确版本的 dll 放在 x86 和 x64 文件夹中解决了这个问题。

                如果你从 Nuget 安装了 Sqlite,你可以在这个文件夹中找到 SQL.Interop.dll(对于 .NET 4.0)

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

                【讨论】:

                • 同样的问题。 Nuget 不会将 SQLite.Interop.dll 添加到输出文件夹。必须通过使用构建后事件自己将其放置在那里。
                【解决方案10】:

                我以为发生了这种情况,因为我在部署文件时正在将文件从输出文件夹复制到另一个位置。我错过了互操作文件被复制的事实,但它们被复制到输出文件夹中的 x64 和 x86 文件夹中。

                如果您在项目的调试中运行 msbuild,您可以查找对 CopySQLiteInteropFiles 目标的引用以确保它正在运行。

                【讨论】:

                • 有趣,我确实在那里看到了它们。那么,它会将它们复制到运行时找不到的地方吗?我想知道它是否应该适用于特定于机器的构建。我尝试了 x86 和 x64 构建,但出现错误。可能是我的问题,不确定。
                • 它们在运行时被发现。如果我删除这些文件夹,我会收到加载错误。如果我不这样做,它会起作用。我只是发现这一点,因为我将文件从输出目录复制到另一个位置以运行,并且我没有复制子目录。
                • 不适合我。我在运行时收到 DllNotFoundException。您的所有项目都构建为 AnyCPU 吗?
                • 就我而言,我必须在启动项目中添加 NuGet 包引用。我们开发的插件之一使用 Sqlite,但仅在该库上添加 NuGet 包不起作用。我不得不将它添加到主项目中。
                • 可能与单元测试项目有关吗?也许,在常规项目中,interop-dll 被正确复制,但在单元测试项目中却没有?
                猜你喜欢
                • 1970-01-01
                • 2018-10-13
                • 2020-06-22
                • 1970-01-01
                • 2023-03-03
                • 1970-01-01
                • 2017-09-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多