首页 文章

NuGet自动包恢复不适用于MSBuild

提问于
浏览
87

我正在尝试使用MSBuild 12.0构建一个缺少 packages 内容的解决方案(除了 repositories.config 内部) . 我希望它能在构建之前自动恢复所有丢失的软件包但事实并非如此--MsBuild报告了大量错误:

“你错过了使用指令或汇编引用吗?”

NuGet Manager是2.7(我在Visual Studio 2013中看到了这个框) . 我甚至试图传递 EnableNuGetPackageRestore=true 参数 - 没有运气 . 我错过了什么?

11 回答

  • 54

    UPDATED with latest official NuGet documentation as of v3.3.0

    包恢复方法

    NuGet提供了三种使用包还原的方法 .


    自动包恢复是NuGet团队在Visual Studio中推荐的包恢复方法,它是在NuGet 2.7中引入的 . 从NuGet 2.7开始,NuGet Visual Studio扩展集成到Visual Studio的构建事件中,并在构建开始时恢复缺少的包 . 默认情况下启用此功能,但开发人员可以根据需要选择退出 .


    以下是它的工作原理:在项目或解决方案构建中,Visual Studio会引发一个事件,即构建在解决方案中开始 . NuGet响应此事件并检查解决方案中包含的packages.config文件 . 对于找到的每个packages.config文件,枚举其包并在解决方案的packages文件夹中存在Checked for . 根据包源的顺序,从用户配置(和启用)的包源中下载任何缺少的包 . 下载软件包后,它们将解压缩到解决方案的软件包文件夹中 .


    如果你安装了Nuget 2.7;选择一种方法来管理Visual Studio中的自动包还原非常重要 . 有两种方法可用:( Nuget 2.7):Visual Studio - >工具 - >包管理器 - >包管理器设置 - >启用自动包恢复(Nuget 2.6及更低版本)右键单击解决方案并单击“为此解决方案启用包恢复” ” .


    从命令行构建解决方案时需要命令行程序包还原;它是在早期版本的NuGet中引入的,但在NuGet 2.7中得到了改进 .

    nuget.exe restore contoso.sln
    

    MSBuild集成的程序包还原方法是最初的程序包还原实现,虽然它在许多方案中继续有效,但它并未涵盖其他两种方法所解决的全套方案 .

  • 0

    如果您使用的是MSBuild 15附带的Visual Studio 2017,并且您的.csproj文件位于new PackageReference format中,则最简单的方法是use the new MSBuild Restore target .


    没有人真的回答了原来的问题,这是"how do I get NuGet packages to auto-restore when building from the command-line with MSBuild?"答案是:除非你使用"Enable NuGet package restore"选项(现在根据this reference弃用),你不能(但见下文) . 如果您正在尝试例如在CI服务器上自动构建,这很糟糕 .

    然而,有一种稍微迂回的方式来获得所需的行为:

    除此之外:虽然新的和推荐的自动包恢复方法涉及到版本控制中较少的混乱,但它也使命令行包恢复变得不可能,除非你跳过额外的下载和运行 nuget.exe . 进展?

  • 31

    如果要从命令行还原包,Nuget 's Automatic Package Restore is a feature of the Visual Studio (starting in 2013), not MSBuild. You'将必须运行 nuget.exe restore .

    您还可以使用“启用Nuget包还原”功能,但nuget人员不再推荐此功能,因为它会对项目文件进行侵入式更改,如果您在其他解决方案中构建这些项目,可能会导致问题 .

  • 2

    我花了一些时间来弄清楚整个画面,我想在这里分享一下 .

    Visual Studio有两种使用包还原的方法:自动包还原和MSBuild集成包还原 . 'MSBuild-Integrated Package Restore'在构建过程中恢复包可能会在某些情况下导致问题 . NuGet团队的'Automatic Package Restore'是the recommended approach .

    有几个步骤可以使“自动包恢复”工作:

    • 在Visual Studio,工具 - >扩展和更新中,如果有更新的版本(版本2.7或更高版本),请升级NuGet

    • 如果使用TFS,请在解决方案的.nuget文件夹中删除NuGet.exe和NuGet.targes文件 . 然后编辑NuGet.Config以不检入NuGet包:

    <configuration>  
      <solution>  
        <add key="disableSourceControlIntegration" value="true" />  
      </solution>  
    </configuration>
    

    如果您之前已将解决方案的packages文件夹签入TFS,请删除该文件夹并检查是否删除了包文件夹删除 .

    如果您不使用TFS,请删除.nuget文件夹 .

    • 在解决方案中的每个项目文件(.csproj或.vbproj)中,删除引用NuGet.targets文件的行 . 参考文字如下:
    <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
    

    在解决方案中的每个项目文件中删除此行 .

    • 在Visual Studio菜单中,通过

    工具 - >选项 - >包管理器 - >常规或工具 - > NuGet包管理器 - >包管理器设置

    请启用以下两个选项:1)'允许NuGet下载丢失的包'2)'在Visual Studio中构建期间自动检查缺少的包'

    • 按以下步骤测试程序包还原配置

    • 保存解决方案并关闭Visual Studio

    • 删除解决方案的包文件夹

    • 启动Visual Studio,打开解决方案并重建它 .

  • 3

    伊恩坎普有答案(有点点btw ..),这只是为他的一个步骤添加一些肉 .

    我最终在这里的原因是dev的机器正在构建良好,但构建服务器根本没有拉下所需的包(空包文件夹),因此构建失败 . 但是,登录到构建服务器并手动构建解决方案 .

    要完成第二个Ians 3点步骤(运行 nuget restore ),您可以创建一个运行exec命令的MSBuild目标来运行nuget restore命令,如下所示(在这种情况下,nuget.exe位于.nuget文件夹中,而不是路径),然后可以在构建解决方案之前立即在TeamCity构建步骤(其他CI可用...)中运行

    <Target Name="BeforeBuild">
      <Exec Command="..\.nuget\nuget restore ..\MySolution.sln"/>
    </Target>
    

    为了记录,我已经尝试了“nuget installer”运行器类型,但这一步骤挂在Web项目上(适用于DLL和Windows项目)

  • 2

    MSBuild 15有/t:restore option这样做 . 它附带Visual Studio 2017 .

    如果你想使用它,你还必须使用新的PackageReference,这意味着用这样的元素替换 packages.config 文件(在* .csproj中这样做):

    <ItemGroup>
      <!-- ... -->
      <PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0" />
      <!-- ... -->
    </ItemGroup>
    
  • 0

    项目中有一个 packages.config 文件,它包含包详细信息 .

    还有一个包含 NuGet.exe and NuGet.targets 的.nuget文件夹 . 如果缺少任何一个文件,它将无法恢复丢失的包并导致"are you missing a using directive or an assembly reference?"错误

  • 17

    请注意,如果您使用TeamCity作为构建服务器,则会获得一个"NuGet Installer"步骤,您可以使用该步骤在构建步骤之前还原所有包 .

  • 214

    有时,当您在"packages"文件夹(即"Packages/EntityFramework.6.0.0/") but the "DLLs" are not inside it (大多数版本控制系统自动忽略".dll"文件)中有要恢复的软件包文件夹时,会发生这种情况 . 这是因为在NuGet尝试恢复每个包之前它会检查文件夹是否已经存在,所以如果存在,NuGet会假定"dll"在其中 . 因此,如果这是你的问题,只需删除NuGet将正确恢复它的文件夹 .

  • 3

    在Visual Studio 2017中 - 使用IDE编译时 - 它将下载所有缺少的nuget包并保存在“packages”文件夹中 .

    但是在构建机器上编译是使用msbuild.exe完成的 . 在那种情况下,我下载了nuget.exe并保存在路径中 .

    在执行msbuild.exe之前的每个构建过程中 . 它将执行 - > nuget.exe恢复NAME_OF_SLN_File(如果只有一个.SLN文件,那么你可以忽略该参数)

  • 2

    我有一个问题,nuget包没有被包含在使用devenv.exe构建sln文件的脚本化每晚构建中 .

    我跟着advice from Microsoft,关键步骤是更新 %AppData%/NuGet 中的NuGet配置,使其包含:

    <configuration>
        <packageRestore>
            <add key="automatic" value="True" />
        </packageRestore>
    </configuration>
    

相关问题