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

One NuGet package (SQLite Core) is causing TFS builds to fail

我的解决方案配置为 "restore packages",但其中一个项目无法构建:-

3>C:\Builds\xxxxx\xxxx.csproj(223,5): error : 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 ..\packages\System.Data.SQLite.Core.1.0.97.0\build\net45\System.Data.SQLite.Core.targets.

这可能是个误会,但上述错误出现在日志中之前 包恢复内容,即

2>RestorePackages:

Restoring NuGet packages...

在有问题的项目的 .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>

这是怎么回事?我是否正确地假设此检查是在解决方案的包恢复之前进行的(因此失败的原因)?我该如何解决这个问题?

解决方案中的其他项目(那些未引用 SQLite 核心包的项目)已将其包恢复正常,并成功构建。

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

先有鸡还是先有蛋 - 软件包尚未恢复,但预构建步骤正在检查软件包文件是否存在!

recommended approach for restoring NuGet packages now seems to be the newer "automatic package restore" feature. My understanding is that this restores NuGet packages before a build starts, avoiding the above issue. Unfortunately this feature isn't supported by TFS 2012. There is a workaround (detailed here) 涉及在您的解决方案中创建一个 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

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

在我的例子中,我检查.csproj中的位置表明确实有System.Data.SQLite.Core.targets文件,然后我重新启动计算机并重新启动visual studio,然后构建成功没有错误.