一个NuGet包(SQLite Core)导致TFS构建失败

And*_*ens 4 system.data.sqlite tfsbuild nuget sqlite-net nuget-package-restore

我的解决方案配置为"恢复包",但其中一个项目未能构建: -

3> C:\ Builds\1\xxxxx\xxxx.csproj(223,5):错误:此项目引用此计算机上缺少的NuGet包.启用NuGet Package Restore以下载它们.有关详细信息,请参阅http://go.microsoft.com/fwlink/?LinkID=322105.丢失的文件是..\packages\System.Data.SQLite.Core.1.0.97.0\build \net45\System.Data.SQLite.Core.targets.

它可能是一个红鲱鱼,但上面的错误出现在包恢复之前的日志中,即

2> RestorePackages:

恢复NuGet包......

在违规项目的.csproj文件的末尾附近是这一<Target>部分,似乎产生了上述错误: -

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
<Import Project="..\packages\System.Data.SQLite.Core.1.0.97.0\build\net45\System.Data.SQLite.Core.targets" Condition="Exists('..\packages\System.Data.SQLite.Core.1.0.97.0\build\net45\System.Data.SQLite.Core.targets')" />

<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
  <PropertyGroup>
    <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
  </PropertyGroup>
  <Error Condition="!Exists('..\packages\System.Data.SQLite.Core.1.0.97.0\build\net45\System.Data.SQLite.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\System.Data.SQLite.Core.1.0.97.0\build\net45\System.Data.SQLite.Core.targets'))" />
</Target>
Run Code Online (Sandbox Code Playgroud)

这是怎么回事?我是否正确地假设这个检查是在解决方案的包甚至已经恢复之前发生的(因此它失败了)?我该如何解决?

解决方案中的其他项目(那些没有引用SQLite核心包的项目)可以很好地恢复它们的包,并且可以成功构建.

And*_*ens 5

我发现这与您在构建期间用于恢复丢失的NuGet包的方法有关.我正在使用众所周知的"启用NuGet包还原"选项(通过右键单击解决方案).问题是有问题的NuGet包("System.Data.SQLite Core(x86/x64)")添加了一个预构建步骤(前面的元素),它检查这个包是否安装了一个名为System.Data的构建目标文件. .SQLite.Core.targets.

想到鸡肉和鸡蛋 - 包装尚未恢复,但预制步骤正在检查包装文件的存在!

现在,恢复NuGet包的推荐方法似乎是较新的"自动包恢复"功能.我的理解是,这会构建开始之前恢复NuGet包,避免上述问题.不幸的是,TFS 2012不支持此功能.有一个解决方法(详细说明)涉及在您的解决方案中创建一个msbuild项目文件,该文件负责在继续构建解决方案之前恢复NuGet包,但这开始感觉到了乱.

对于任何有兴趣(或熟悉SQLite.Net)的人来说,这就是我为解决问题所做的:

我删除了"System.Data.SQLite Core(x86/x64)"包,并添加了包"System.Data.SQLite Core MSIL".这仅包含托管System.Data.SQLite.dll程序集,并且不会使用自定义构建目标执行任何操作.

此程序集依赖于本机SQLite.Interop.dll,但由于某些奇怪的原因,设计用于在[bin]\x86或[bin]\x64子文件夹中查找(取决于体系结构).这些互操作DLL是我删除的原始包的一部分; 它的构建目标(导致我的问题)负责将DLL复制到这些子文件夹.

为了解决这个问题,我将x86和x64互操作DLL添加到我的项目中,如下所示: -

FooProject
  \x86
     SQLite.Interop.dll
  \x864
     SQLite.Interop.dll
Run Code Online (Sandbox Code Playgroud)

我确定他们Build Action是"内容",然后将他们的Copy to Output Directory设置更改为"始终复制".当"内容"文件被复制到输出文件夹时,项目文件夹结构将被保留,因此它是创建[bin]\x86和[bin]\x64子文件夹及其各自DLL的便捷方式.