【问题标题】:SQLite.Interop.dll files does not copy to project output path when required by referenced project引用项目需要时,SQLite.Interop.dll 文件不会复制到项目输出路径
【发布时间】:2015-12-14 20:55:21
【问题描述】:

我在 Visual Studio 2015 中使用 System.Data.SQLite Core Version: 1.0.98.1 nuget 包。当我构建引用我的 System.Data.SQLite 包的项目时,它会分别复制两个文件夹(x86 和 x64)包含 SQLite.Interop.dll 到输出目录。但是,当我构建我的测试项目或引用前面提到的项目的任何其他项目时,这些文件夹不会被复制到父项目的输出目录,并且我在 SQLite.Interop.dll 上得到一个 DllNotFoundException。

注意:特别是当引用 System.Data.SQLite 的项目被另一个项目引用时

【问题讨论】:

    标签: sqlite nuget system.data.sqlite


    【解决方案1】:

    推荐的解决方案为here 是在您的 packages\System.Data.SQLite.Core.1.0.98.1\build\[您的框架版本在这里] 中创建一个 System.Data.SQLite.Core.targets.user文件夹包含

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

    但是,如果您不想将包文件夹中的任何内容添加到源代码管理中,则可以直接将以下内容添加到项目文件中

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

    SDK 风格项目更新

    在新的 SDK 项目样式中,解决嵌套项目和包之间的依赖关系的方式发生了变化。在构建过程中,资产被解析并生成一个obj\project.assets.json 文件,列出来自所有各种依赖项的资产。然后使用项目资产文件来确定需要导入哪些目标以及需要将哪些文件复制到输出目录。 但是,如何从非直接依赖项中包含资产是有区别的。不导入非直接依赖项的build 文件夹中的目标文件。旧的解决方法取决于将System.Data.SQLite.Core.targets 导入到父项目中。直接依赖于System.Data.Sqlite 的项目可以通过将PrivateAssets="none" 添加到PackageImport 来覆盖此行为。您还需要将此添加到依赖项链中的每个 PackageImport 或 ProjectReference`。但是,您不需要将其与之前的解决方法结合使用。

    TLDR

    在直接引用 System.Data.Sqlite 的项目中,将 PrivateAssets="none" 添加到您的 PackageImport

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

    对于你的依赖链中的每个项目,直到你的根项目,还要添加PrivateAssets="none"

    <ProjectReference Include="..\MyProject.csproj" PrivateAssets="none"/>
    

    【讨论】:

    • 我的本地构建工作正常——CopySQLiteInteropFiles 运行并将文件复制到我机器上的 OutDir。但是在我对 TeamCity 的测试中,同样的构建失败了——Dll 在丢失的互操作文件上没有发现异常。在我的 proj 文件中创建 CopySQLiteInteropFiles 属性是让 TeamCity 复制互操作文件的方法。 +1
    • 第二种解决方案对我来说效果很好。从 nuget 获得新版本后,建议不会立即中断吗?
    • 我有一个使用 sqlite 引用 SDK 项目的 winform 项目,我尝试在 sdk 和 winworm 中都使用 PrivateAssets="none" 但 winform 项目既没有 bin 也没有 interop dll发布文件列表。 (vs2019)有什么想法吗?
    • 好的,所以只需将PrivateAssets="none" 添加到链中的每个依赖项都对我有用!这也可以通过 VS UI 作为 nuget 参考上的属性获得。请注意,我没有为其中一个链中的最后一个非 SDK 样式项目做任何事情,它也在那里工作。
    【解决方案2】:

    &lt;ContentSQLiteInteropFiles&gt;true&lt;/ContentSQLiteInteropFiles&gt; 似乎对 .NET Standard 2.0 无效,其中 SQLite.interop.dll 在引用项目中仍然未被识别为内容或依赖项。

    我希望有人为此找到更清洁的解决方案...

    <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>
    

    【讨论】:

    • @BenCamps 谢谢,这看起来更干净 - 但正如您所说,这将要求所有其他项目也设置包属性,而我目前的解决方法没有。
    • 但是,新的 SDK 样式项目格式不再使用位于项目目录中的 packages 文件夹。新的包文件夹位于 %userprofile%/.nuget/packages。但更简洁的解决方案是使用GeneratePathsProperty 在您的项目文件中创建一个变量以引用可能存在的包目录。
    • @BenCamps 啊,感谢您的提醒!我猜我的旧包文件夹是完整的,因为我刚刚升级。我已经相应地更新了我的答案。
    • 这很好用,但是在创建我的项目的 nuget 包时会出现错误。 NuGet.Build.Tasks.Pack.targets(221, 5):[NU5118] 未添加文件,因为包已包含文件“content\SQLite.Interop.dll”。 NuGet.Build.Tasks.Pack.targets(221, 5): [NU5100] 程序集 'content\SQLite.Interop.dll' 不在 'lib' 文件夹中,因此在包被安装到一个项目中。如果需要引用,请将其移动到“lib”文件夹中。有没有其他人遇到过这个?
    猜你喜欢
    • 2010-11-25
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 2018-08-15
    • 1970-01-01
    • 2020-08-31
    • 2014-10-06
    • 1970-01-01
    相关资源
    最近更新 更多