La restauración automática de paquetes de NuGet no funciona con MSBuild

111

Estoy tratando de crear una solución con packagescontenido faltante (excepto en el repositories.configinterior) con MSBuild 12.0. Espero que restaure automáticamente todos los paquetes faltantes antes de compilar, pero este no es el caso: MsBuild informa toneladas de errores:

"¿Le falta una directiva using o una referencia de ensamblado?"

NuGet Manager es 2.7 (veo esto en Visual Studio 2013 sobre el cuadro). Incluso intenté pasar el EnableNuGetPackageRestore=trueparámetro, sin suerte. ¿Qué me estoy perdiendo?

Control de usuario
fuente
¿Está creando la solución dentro de Visual Studio? ¿También está todo marcado en la Configuración del Administrador de paquetes en la sección Restaurar paquete? No necesita la carpeta .nuget si está compilando dentro de Visual Studio y usa NuGet 2.7 o superior.
Matt Ward
1
No, estoy usando la última versión de MsBuild ( msdn.microsoft.com/en-us/library/hh162058.aspx ) desde la línea de comandos. Nuget actualizado desde dentro de VS a 2.8, sin suerte.
UserControl
3
MSBuild por sí solo no se restaurará y el complemento VS tampoco. Debe habilitar la restauración de paquetes como dijo @KMoraz, y luego, como dijo Sumeshk, aparece la carpeta .nuget y los paquetes se pueden restaurar. Asegúrese de registrar .nuget en el control de código fuente.
Lex Li

Respuestas:

36

ACTUALIZADO con la documentación oficial más reciente de NuGet a partir de v3.3.0

Enfoques de restauración de paquetes

NuGet ofrece tres enfoques para usar la restauración de paquetes .


La restauración automática de paquetes es el enfoque recomendado por el equipo de NuGet para la restauración de paquetes dentro de Visual Studio y se introdujo en NuGet 2.7. A partir de NuGet 2.7, la extensión de NuGet Visual Studio se integra en los eventos de compilación de Visual Studio y restaura los paquetes faltantes cuando comienza una compilación. Esta función está habilitada de forma predeterminada, pero los desarrolladores pueden optar por no participar si lo desean.


Así es como funciona:

  1. En la compilación del proyecto o la solución, Visual Studio genera un evento de que una compilación está comenzando dentro de la solución.
  2. NuGet responde a este evento y comprueba los archivos packages.config incluidos en la solución.
  3. Para cada archivo packages.config encontrado, sus paquetes se enumeran y se comprueba si existe en la carpeta de paquetes de la solución.
  4. Los paquetes que faltan se descargan de las fuentes del paquete configuradas (y habilitadas) del usuario, respetando el orden de las fuentes del paquete.
  5. A medida que se descargan los paquetes, se descomprimen en la carpeta de paquetes de la solución.

Si tiene Nuget 2.7+ instalado; es importante elegir un método para> administrar la restauración automática de paquetes en Visual Studio.

Hay dos métodos disponibles:

  1. (Nuget 2.7+): Visual Studio -> Herramientas -> Administrador de paquetes -> Configuración del administrador de paquetes -> Habilitar restauración automática de paquetes
  2. (Nuget 2.6 y versiones anteriores) Haga clic con el botón derecho en una solución y haga clic en "Habilitar restauración de paquetes para esta solución".


La restauración del paquete de la línea de comandos es necesaria cuando se crea una solución desde la línea de comandos; se introdujo en las primeras versiones de NuGet, pero se mejoró en NuGet 2.7.

nuget.exe restore contoso.sln

El enfoque de restauración de paquetes integrado en MSBuild es la implementación original de restauración de paquetes y, aunque sigue funcionando en muchos escenarios, no cubre el conjunto completo de escenarios abordados por los otros dos enfoques.

KMoraz
fuente
63
Nuget ya no recomienda esto. Consulte los documentos. docs.nuget.org/docs/workflows/…
Owen Johnson
@OwenJohnson, ese documento no está fechado que yo pueda ver y no veo cómo dice que no se recomienda ahora. Estoy en VS2013 y ese botón parece funcionar bien. No hice referencia al problema, "Entonces, hizo clic en" Habilitar restauración de paquete Nuget "y ahora sus cosas no se compilan. Los pasos para solucionarlo son dolorosos, pero menos dolorosos con este script". Github.com/owen2/ AutomaticPackageRestoreMigrationScript Quizás haya otro documento que explique esto con más detalle.
AnneTheAgile
5
La restauración automática de paquetes reemplaza la restauración integrada de ms-build. El documento contiene las instrucciones sobre cómo actualizar. Si no tiene problemas con el método integrado de msbuild, no necesita hacer nada. En los casos más simples, funciona, pero si tiene servidores de CI, referencias de proyectos compartidas o algunas otras condiciones, puede pisar algunas minas terrestres desagradables y tener rutas de pistas incorrectas u otros problemas.
Owen Johnson
1
Usando esta respuesta Y haciendo las instrucciones para "eliminar cosas viejas" "Realización de la migración" en docs.nuget.org/consume/package-restore/… , pude encontrar el éxito.
granadaCoder
Parece que las cosas han vuelto a cambiar con NuGet 4 y el estándar .net.
Owen Johnson
239

Si está utilizando Visual Studio 2017 o posterior que se incluye con MSBuild 15 o posterior, y sus archivos .csproj están en el nuevo PackageReferenceformato , el método más simple es usar el nuevo Restoredestino de MSBuild .


En realidad, nadie ha respondido a la pregunta original, que es "¿cómo consigo que los paquetes NuGet se restauren automáticamente al compilar desde la línea de comandos con MSBuild?" La respuesta es: a menos que esté utilizando la opción "Habilitar la restauración del paquete NuGet" (que ahora está en desuso según esta referencia ), no puede (pero vea a continuación). Si está intentando hacer, por ejemplo, compilaciones automatizadas en un servidor CI, esto apesta.

Sin embargo, hay una forma un poco indirecta de obtener el comportamiento deseado:

  1. Descargue el último ejecutable de NuGet desde https://dist.nuget.org/win-x86-commandline/latest/nuget.exe y colóquelo en algún lugar de su RUTA. (Puede hacer esto como un paso previo a la compilación).
  2. Ejecutar, nuget restoreque descargará automáticamente todos los paquetes faltantes.
  3. Ejecute msbuildpara construir su solución.

Aparte: si bien la forma nueva y recomendada de realizar la restauración automática de paquetes implica menos desorden en su control de versiones, también hace que la restauración de paquetes desde la línea de comandos sea imposible a menos que pase por el aro adicional de descargar y ejecutar nuget.exe. ¿Progreso?

Ian Kemp
fuente
Terminó con una solución similar (pero colocada nuget.exeen / trunk / ext). Un paso adelante - dos pasos atrás :(
UserControl
40
Esta debe ser una respuesta correcta, no la marcada.
Woland
Esto realmente parece ser un poco contrario a la intuición cuando se trata de eso, pero realmente obtienes más funcionalidades para agregar paquetes nuget específicos usando la línea de comando. Esta solución funcionó para mí mientras fallaba la restauración automática.
TGarrett
2
Estaba usando Jenkins y tuve que hacer esto, fue un paso de compilación simple antes de llamar a msbuild: el archivo por lotes de Windows era el tipo de paso de compilación y: cmd.exe / c "C: \ Archivos de programa \ nuget \ nuget.exe" restaurar < RelativePathToSln> .sln - Hice la ruta a SLN como un hábito / procedimiento en caso de que no encontrara el archivo sln.
Steve Radich-BitShop.com
1
Este enfoque funcionó para mí al configurar una restauración en una compilación de Jenkins. Una clave importante para mí fue que NuGet.Config tenía que estar en el mismo directorio que mi archivo .SLN. Ninguna combinación de otras ubicaciones de archivos de configuración, incluida la especificación de -ConfigFile en la línea de comandos, funcionaría.
Guerry
56

La restauración automática de paquetes de Nuget es una característica de Visual Studio (a partir de 2013), no MSBuild. Deberá ejecutarlo nuget.exe restoresi desea restaurar paquetes desde la línea de comando.

También puede usar la función Habilitar restauración de paquetes de Nuget, pero la gente de nuget ya no la recomienda porque realiza cambios intrusivos en los archivos del proyecto y puede causar problemas si crea esos proyectos en otra solución.

Owen Johnson
fuente
2
Debe ejecutar "nuget update -self" antes de usar el comando restore si su versión de NuGet no es al menos 2.7. Mi NuGet era la versión 2.1 y no reconocía el comando "restaurar" antes de actualizar.
Teknikaali
2
"causa problemas si construye esos proyectos en otra solución" No he tenido ningún problema todavía y tenemos 3 soluciones con docenas de proyectos cada una (muchos compartidos entre soluciones). ¿Quizás tuve suerte?
Nelson Rothermel
@NelsonRothermel, la situación problemática más notable que puede suceder son los proyectos que hacen referencia a dlls entregados por nuget a la carpeta de paquetes de una solución externa, que puede no estar disponible cuando se crea una solución.
Owen Johnson
2
@OwenJohnson Tenemos una carpeta de paquete común para todas las soluciones, por lo que probablemente no hemos tenido problemas.
Nelson Rothermel
17

Me tomó un tiempo darme cuenta de la imagen completa y me gustaría compartirla aquí.

Visual Studio tiene dos enfoques para usar la restauración de paquetes: Restauración automática de paquetes y Restauración de paquetes integrada de MSBuild. La 'Restauración de paquetes integrada de MSBuild' restaura paquetes DURANTE el proceso de construcción que pueden causar problemas en algunos escenarios. La 'Restauración automática de paquetes' es el enfoque recomendado por el equipo de NuGet.

Hay varios pasos para que funcione la 'Restauración automática de paquetes':

  1. En Visual Studio, Herramientas -> Extensiones y actualizaciones, actualice NuGet si hay una versión más reciente (Versión 2.7 o posterior)

  2. Si usa TFS, en la carpeta .nuget de su solución, elimine los archivos NuGet.exe y NuGet.targes. Luego edite NuGet.Config para no registrar los paquetes de NuGet:

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

    Si ha registrado la carpeta de paquetes de la solución en TFS antes, elimine la carpeta y verifique la eliminación de la eliminación de la carpeta del paquete.

    Si no usa TFS, elimine la carpeta .nuget.

  3. En cada archivo de proyecto (.csproj o .vbproj) de su solución, elimine la línea que hace referencia al archivo NuGet.targets. La referencia se ve así:

    <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />

    Elimine esta línea en cada archivo de proyecto en su solución.

  4. En el menú de Visual Studio, ya sea a través de

    Herramientas -> Opciones -> Administrador de paquetes -> General o Herramientas -> Administrador de paquetes NuGet -> Configuración del administrador de paquetes

    habilite las siguientes dos opciones 1) 'Permitir que NuGet descargue los paquetes que faltan' 2) 'Verifique automáticamente los paquetes que faltan durante la compilación en Visual Studio'

  5. Pruebe la configuración de restauración de su paquete siguiendo los siguientes pasos

    • Guarde su solución y cierre Visual Studio
    • Elimina la carpeta de paquetes de tu solución
    • Inicie Visual Studio, abra su solución y vuelva a generarla.
Ying
fuente
1
Uno de sus pasos es eliminar <Import Project = "$ (MSBuildToolsPath) \ Microsoft.CSharp.targets" />. ¿Por qué harías eso?
Sayed Ibrahim Hashimi
3
Creo que te equivocas porque está en la propia plantilla. Sin él, sus archivos fuente no se construirán en absoluto.
Sayed Ibrahim Hashimi
3
Creo que se refería a nuget.targets en lugar de Microsoft.CSharp.targets.
Owen Johnson
2
docs.nuget.org/docs/workflows/… <- Aquí están los documentos oficiales de lo que Ying estaba tratando de decir.
Owen Johnson
1
Ying tiene razón ... lo que todos han ignorado es el hecho de que las compilaciones de Integración Continua crean su propio espacio de trabajo temporal DESPUÉS de los eventos previos a la compilación, obtienen las fuentes y luego se atragantan con las referencias de NuGet. Este es EL CORRECCIÓN para la automatización de compilación de TFS.
CZahrobsky
5

MSBuild 15 tiene una opción / t: restore que hace esto. viene con Visual Studio 2017.

Si desea usar esto, también debe usar el nuevo PackageReference , lo que significa reemplazar el packages.configarchivo con elementos como este (haga esto en * .csproj):

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

Hay una migración automatizada a este formato si hace clic con el botón derecho en 'Referencias' (es posible que no aparezca si acaba de abrir Visual Studio, reconstruir o abrir la ventana 'Administrar paquetes NuGet para la solución' y comenzará a aparecer).

Chris
fuente
Debe tener en cuenta que la opción de restauración de msbuild tiene diferencias sutiles con la restauración de nuget; consulte github.com/NuGet/Home/issues/7651#issuecomment-500842049 por ejemplo.
Matthieu
4

Ian Kemp tiene la respuesta (tiene algunos puntos por cierto ...), esto es simplemente agregar algo de carne a uno de sus pasos.

La razón por la que terminé aquí fue que las máquinas de desarrollo se estaban construyendo bien, pero el servidor de compilación simplemente no estaba eliminando los paquetes requeridos (carpeta de paquetes vacía) y, por lo tanto, la compilación estaba fallando. Sin embargo, iniciar sesión en el servidor de compilación y compilar manualmente la solución funcionó.

Para cumplir con el segundo de los pasos de 3 puntos de Ians (ejecutar la restauración de nuget ), puede crear un destino MSBuild ejecutando el comando exec para ejecutar el comando de restauración de nuget, como se muestra a continuación (en este caso, nuget.exe está en la carpeta .nuget, en lugar de en la ruta), que luego se puede ejecutar en un paso de compilación de TeamCity (otros CI disponibles ...) inmediatamente antes de compilar la solución

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

Para el registro, ya probé el tipo de corredor "instalador nuget", pero este paso estaba colgado en proyectos web (funcionó para proyectos de DLL y Windows)

Fetchez la vache
fuente
1
Si está construyendo constantemente a partir de un nuevo conjunto de código (CI), este es el camino a seguir.
Jahmic
1
Me gusta un poco este enfoque porque garantiza que cada solución / proyecto se basa en la versión de nuget con la que se creó. A su debido tiempo, esto puede resultar vital si trabaja en una empresa con proyectos antiguos que se crearon con versiones antiguas de nuget. Un desarrollador puede mantener dichos proyectos sin tener que preocuparse de si nuget.exe en todo el sistema romperá las cosas porque cada proyecto tiene su propio "sabor local" de nuget.exe. Como último consejo, vale la pena señalar que con nuget 3.x + podemos restaurar paquetes de esta manera: nuget.exe restore packages.config -PackagesDirectory path \ to \ packages
XDS
1
El problema que tengo con este enfoque es que deberá editar cualquier archivo de proyecto posterior para agregar el paso de restauración. puede agregar una actividad "InvokeProcess" en TFS2012 o una actividad "NuGetRestore" en la plantilla de compilación TFS2013 para que este paso se ejecute en el servidor de compilación. para InvokeProcess, pase el atributo "SourcesDirectory" en 2012. En TFS 2013, simplemente complete los valores según sea necesario. hay muchos blogs sobre cómo hacer esto.
Neville
3

Tenga en cuenta que si está utilizando TeamCity como un servidor de compilación, obtendrá un paso de "Instalador NuGet" que puede usar para restaurar todos los paquetes antes del paso de compilación.

Dejan
fuente
2

Hay un archivo packages.config con el proyecto, que contiene los detalles del paquete.

También hay una carpeta .nuget que contiene NuGet.exe y NuGet.targets . si falta alguno de los archivos, no restaurará el paquete faltante y causará "¿le falta una directiva using o una referencia de ensamblado?" error

Sumeshk
fuente
2
No hay .nugetcarpeta y nunca la hubo. Todos los packages.configarchivos dentro de las carpetas del proyecto están en su lugar.
UserControl
Creo que NuGet.exe y NuGet.targets restaurarán automáticamente todos los paquetes faltantes mientras se compila la aplicación y perdió sus archivos NuGet.exe y NuGet.targets, eso es lo que causa errores
Sumeshk
Gracias de todos modos -¡Aprecio cualquier ayuda!
UserControl
la carpeta .nuget es una carpeta generada por Visual Studio, que aparece solo cuando habilita la restauración automática de paquetes. Es útil tener nuget.exe en su repositorio de código, ya que puede hacer referencia a él en sus compilaciones, al igual que nuget.config (especialmente si necesita obtener paquetes de varios repositorios).
MytyMyky
2

A veces, esto ocurre cuando tiene la carpeta del paquete que está intentando restaurar dentro de la carpeta "paquetes" (es decir, "Paquetes / EntityFramework.6.0.0 /" ) pero las "DLL" no están dentro (la mayoría del control de versiones los sistemas ignoran automáticamente los archivos ".dll"). Esto ocurre porque antes de que NuGet intente restaurar cada paquete, verifica si las carpetas ya existen, por lo que, si existe, NuGet asume que el "dll" está dentro. Entonces, si este es el problema, simplemente elimine la carpeta que NuGet la restaurará correctamente.

fabriciorissetto
fuente
1
Para VS 2015 y TFS, esto lo solucionará. El problema será una referencia no resuelta y, a menudo, el problema es que el paquete nuget no se está restaurando porque la carpeta del paquete ya existe en la carpeta de paquetes, pero aún así el paquete no se ha expandido completamente correctamente. (Por ejemplo, falta una carpeta lib que debería contener un .dll). Elimine toda la carpeta del paquete dentro de los paquetes y luego haga clic con el botón derecho en el nivel de la solución y elija restaurar los paquetes.
Greg
1

Tuve un problema con los paquetes nuget que no se incluían en una compilación nocturna con script que compila el archivo sln usando devenv.exe.

Seguí el consejo de Microsoft y el paso clave fue actualizar la configuración de NuGet %AppData%/NuGetpara que contuviera:

<configuration>
    <packageRestore>
        <add key="automatic" value="True" />
    </packageRestore>
</configuration>
PaulG
fuente
Entonces verifiqué que cuando cambia la configuración en Visual Studio (la mayoría de las respuestas aquí) ... lo anterior es en realidad lo que cambia. la otra "clave" es <add key = "enabled" value = "False" />.
granadaCoder
0

En Visual Studio 2017, cuando compila usando IDE, descargará todos los paquetes nuget que faltan y los guardará en la carpeta "paquetes".

Pero en la máquina de compilación, la compilación se realizó con msbuild.exe. En ese caso, descargué nuget.exe y mantuve la ruta.

Durante cada proceso de compilación antes de ejecutar msbuild.exe. Se ejecutará -> nuget.exe restaurar NAME_OF_SLN_File (si solo hay un archivo .SLN, entonces puede ignorar ese parámetro)

David
fuente
0

También puedes usar

Update-Package -reinstall

para restaurar los paquetes NuGet en la Consola de administración de paquetes en Visual Studio.

MovGP0
fuente
Esta no es una respuesta a esta pregunta
TS