La restauration automatique des packages NuGet ne fonctionne pas avec MSBuild

111

J'essaie de créer une solution avec du packagescontenu manquant (sauf à l' repositories.configintérieur) avec MSBuild 12.0. Je m'attends à ce qu'il restaure automatiquement tous les paquets manquants avant la construction, mais ce n'est pas le cas - MsBuild rapporte des tonnes d'erreurs:

"vous manque une directive using ou une référence d'assemblage?"

NuGet Manager est 2.7 (je vois cela dans Visual Studio 2013 à propos de la boîte). J'ai même essayé de passer le EnableNuGetPackageRestore=trueparamètre - pas de chance. Qu'est-ce que je rate?

UserControl
la source
Créez-vous la solution dans Visual Studio? Est-ce que tout est également coché dans les paramètres du gestionnaire de packages dans la section Restauration de packages? Vous n'avez pas besoin du dossier .nuget si vous créez dans Visual Studio et utilisez NuGet 2.7 ou supérieur.
Matt Ward
1
Non, j'utilise la dernière version de MsBuild ( msdn.microsoft.com/en-us/library/hh162058.aspx ) à partir de la ligne de commande. Mise à jour de Nuget depuis VS vers 2.8 - pas de chance.
UserControl
3
MSBuild seul ne restaurera pas et le complément VS non plus. Vous devez activer la restauration de paquet comme @KMoraz l'a dit, puis comme Sumeshk l'a dit, le dossier .nuget apparaît et les paquets peuvent être restaurés. Assurez-vous de vérifier .nuget dans le contrôle de code source.
Lex Li

Réponses:

36

MISE À JOUR avec la dernière documentation officielle NuGet à partir de la v3.3.0

Approches de restauration de package

NuGet propose trois approches pour utiliser la restauration de package .


La restauration automatique de packages est l'approche recommandée par l'équipe NuGet pour la restauration de packages dans Visual Studio, et elle a été introduite dans NuGet 2.7. À partir de NuGet 2.7, l'extension NuGet Visual Studio s'intègre aux événements de génération de Visual Studio et restaure les packages manquants au début d'une génération. Cette fonctionnalité est activée par défaut, mais les développeurs peuvent la désactiver s'ils le souhaitent.


Voici comment ça fonctionne:

  1. Lors de la génération de projet ou de solution, Visual Studio déclenche un événement indiquant qu'une génération commence dans la solution.
  2. NuGet répond à cet événement et recherche les fichiers packages.config inclus dans la solution.
  3. Pour chaque fichier packages.config trouvé, ses packages sont énumérés et Vérifié existe dans le dossier packages de la solution.
  4. Tous les packages manquants sont téléchargés à partir des sources de package configurées (et activées) de l'utilisateur, en respectant l'ordre des sources de package.
  5. Au fur et à mesure que les packages sont téléchargés, ils sont décompressés dans le dossier packages de la solution.

Si vous avez installé Nuget 2.7+; il est important de choisir une méthode pour> gérer la restauration automatique des packages dans Visual Studio.

Deux méthodes sont disponibles:

  1. (Nuget 2.7+): Visual Studio -> Outils -> Gestionnaire de package -> Paramètres du gestionnaire de package -> Activer la restauration automatique de package
  2. (Nuget 2.6 et ci-dessous) Faites un clic droit sur une solution et cliquez sur "Activer la restauration de package pour cette solution".


La restauration de package en ligne de commande est requise lors de la création d'une solution à partir de la ligne de commande; il a été introduit dans les premières versions de NuGet, mais a été amélioré dans NuGet 2.7.

nuget.exe restore contoso.sln

L' approche de restauration de package intégrée à MSBuild est l'implémentation de restauration de package d'origine et bien qu'elle continue de fonctionner dans de nombreux scénarios, elle ne couvre pas l'ensemble complet des scénarios traités par les deux autres approches.

KMoraz
la source
63
Ce n'est plus recommandé par nuget. Consultez la documentation. docs.nuget.org/docs/workflows/…
Owen Johnson
@OwenJohnson, ce document n'est pas daté que je peux voir et je ne vois pas comment il dit qu'il n'est pas recommandé maintenant? Je suis sur VS2013 et ce bouton semble fonctionner correctement. Je n'ai pas eu le problème référencé, "Donc, vous avez cliqué sur" Activer la restauration du package Nuget "et maintenant votre truc ne se construit pas. Les étapes pour le résoudre sont douloureuses, mais moins douloureuses avec ce script." Github.com/owen2/ AutomaticPackageRestoreMigrationScript Il existe peut-être un autre document qui explique cela plus en détail.
AnneTheAgile
5
La restauration automatique des packages remplace la restauration intégrée ms-build. Le document contient les instructions de mise à niveau. Si vous ne rencontrez pas de problèmes avec la méthode intégrée à msbuild, vous n'avez rien à faire. Dans les cas les plus simples, cela fonctionne, mais si vous avez des serveurs CI, des références de projet partagées ou d'autres conditions, vous pouvez marcher sur des mines terrestres désagréables et avoir des indices incorrects ou d'autres problèmes.
Owen Johnson
1
En utilisant cette réponse ET en exécutant les instructions "Supprimer les anciens éléments" "Effectuer la migration" sur docs.nuget.org/consume/package-restore/... , j'ai pu trouver le succès.
granadaCoder
On dirait que les choses ont encore changé avec NuGet 4 et la norme .net.
Owen Johnson
239

Si vous utilisez Visual Studio 2017 ou version ultérieure, livré avec MSBuild 15 ou version ultérieure, et que vos fichiers .csproj sont au nouveau PackageReferenceformat , la méthode la plus simple consiste à utiliser la nouvelle Restorecible MSBuild .


Personne n'a en fait répondu à la question initiale, qui est «comment faire restaurer automatiquement les packages NuGet lors de la création à partir de la ligne de commande avec MSBuild?» La réponse est: à moins que vous n'utilisiez l'option «Activer la restauration du package NuGet» (qui est désormais obsolète selon cette référence ), vous ne pouvez pas (mais voir ci-dessous). Si vous essayez de faire par exemple des builds automatisés sur un serveur CI, cela craint.

Cependant, il existe un moyen légèrement détourné pour obtenir le comportement souhaité:

  1. Téléchargez le dernier exécutable NuGet à partir de https://dist.nuget.org/win-x86-commandline/latest/nuget.exe et placez-le quelque part dans votre PATH. (Vous pouvez le faire en tant qu'étape de pré-construction.)
  2. Exécuter nuget restorequi téléchargera automatiquement tous les packages manquants.
  3. Exécutez msbuildpour créer votre solution.

Mis à part: bien que la méthode nouvelle et recommandée pour effectuer la restauration automatique des packages implique moins d'encombrement dans votre contrôle de version, elle rend également la restauration de packages en ligne de commande impossible à moins que vous ne passiez par le cercle supplémentaire du téléchargement et de l'exécution nuget.exe. Le progrès?

Ian Kemp
la source
Terminé avec une solution similaire (mais placée nuget.exedans / trunk / ext). Un pas en avant - deux pas en arrière :(
UserControl
40
Cela devrait être une réponse correcte, pas celle marquée.
Woland
Cela semble vraiment être un peu contre-intuitif, mais vous obtenez vraiment plus de fonctionnalités pour ajouter des packages nuget spécifiques en utilisant la ligne de commande. Cette solution a fonctionné pour moi alors que la restauration automatique a échoué.
TGarrett
2
J'utilisais Jenkins et devais le faire, c'était une étape de construction simple avant d'appeler msbuild - le fichier de commandes Windows était le type d'étape de construction et: cmd.exe / c "C: \ Program Files \ nuget \ nuget.exe" restaurer < RelativePathToSln> .sln - J'ai fait le chemin vers SLN comme habitude / procédure juste au cas où il ne trouverait pas le fichier sln.
Steve Radich-BitShop.com
1
Cette approche a fonctionné pour moi lors de la configuration d'une restauration sur une version Jenkins. Une clé importante pour moi était que le NuGet.Config devait être dans le même répertoire que mon fichier .SLN. Aucune combinaison d'autres emplacements de fichier de configuration, y compris la spécification -ConfigFile sur la ligne de commande ne fonctionnerait.
Guerry
56

La restauration automatique des packages de Nuget est une fonctionnalité de Visual Studio (à partir de 2013), et non de MSBuild. Vous devrez exécuter nuget.exe restoresi vous souhaitez restaurer des packages à partir de la ligne de commande.

Vous pouvez également utiliser la fonctionnalité Activer la restauration de packages Nuget, mais cela n'est plus recommandé par les utilisateurs de Nuget, car elle apporte des modifications intrusives aux fichiers de projet et peut causer des problèmes si vous générez ces projets dans une autre solution.

Owen Johnson
la source
2
Vous devez exécuter "nuget update -self" avant d'utiliser la commande restore si votre version de NuGet n'est pas au moins 2.7. Mon NuGet était la version 2.1 et n'a pas reconnu la commande "restore" avant la mise à jour.
Teknikaali
2
"cause des problèmes si vous construisez ces projets dans une autre solution" Je n'ai pas encore rencontré de problèmes et nous avons 3 solutions avec des dizaines de projets chacune (dont beaucoup sont partagées entre les solutions). Peut-être ai-je eu de la chance?
Nelson Rothermel
@NelsonRothermel, la situation problématique la plus notable qui puisse se produire est celle des projets référençant des dll livrées par nuget au dossier packages d'une solution étrangère, qui peut ne pas être disponible lorsque vous créez une solution.
Owen Johnson
2
@OwenJohnson Nous avons un dossier de package commun pour toutes les solutions, c'est probablement pourquoi nous n'avons pas rencontré de problèmes.
Nelson Rothermel
17

Il m'a fallu un certain temps pour comprendre l'image dans son ensemble et j'aimerais partager ici.

Visual Studio a deux approches pour utiliser la restauration de package: la restauration automatique de package et la restauration de package intégrée à MSBuild. La 'Restauration de package intégrée à MSBuild' restaure les packages PENDANT le processus de construction, ce qui peut entraîner des problèmes dans certains scénarios. La «restauration automatique des packages» est l'approche recommandée par l'équipe NuGet.

Il existe plusieurs étapes pour faire fonctionner la `` restauration automatique des packages '':

  1. Dans Visual Studio, Outils -> Extensions et mises à jour, mettez à niveau NuGet s'il existe une version plus récente (version 2.7 ou ultérieure)

  2. Si vous utilisez TFS, dans le dossier .nuget de votre solution, supprimez les fichiers NuGet.exe et NuGet.targes. Puis modifiez NuGet.Config pour ne pas archiver les packages NuGet:

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

    Si vous avez déjà archivé le dossier packages de la solution dans TFS, supprimez le dossier et vérifiez la suppression de la suppression du dossier package.

    Si vous n'utilisez pas TFS, supprimez le dossier .nuget.

  3. Dans chaque fichier projet (.csproj ou .vbproj) de votre solution, supprimez la ligne qui fait référence au fichier NuGet.targets. La référence ressemble à ceci:

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

    Supprimez cette ligne dans chaque fichier de projet de votre solution.

  4. Dans le menu Visual Studio, soit via

    Outils -> Options -> Gestionnaire de package -> Général ou Outils -> Gestionnaire de package NuGet -> Paramètres du gestionnaire de package

    veuillez activer les deux options suivantes 1) 'Autoriser NuGet à télécharger les packages manquants' 2) 'Rechercher automatiquement les packages manquants lors de la génération dans Visual Studio'

  5. Testez la configuration de la restauration de votre package en suivant les étapes suivantes

    • Enregistrez votre solution et fermez Visual Studio
    • Supprimer le dossier packages de votre solution
    • Démarrez Visual Studio, ouvrez votre solution et reconstruisez-la.
Ying
la source
1
L'une de vos étapes consiste à supprimer <Import Project = "$ (MSBuildToolsPath) \ Microsoft.CSharp.targets" />. Pourquoi ferais-tu ça?
Sayed Ibrahim Hashimi
3
Je pense que vous vous trompez, c'est dans le modèle lui-même. Sans cela, vos fichiers source ne seront pas du tout créés.
Sayed Ibrahim Hashimi
3
Je pense qu'il voulait dire nuget.targets au lieu de Microsoft.CSharp.targets.
Owen Johnson
2
docs.nuget.org/docs/workflows/… <- Voici la documentation officielle de ce que Ying essayait de dire.
Owen Johnson
1
Ying a raison ... ce que tout le monde a ignoré, c'est le fait que les builds d'intégration continue créent leur propre espace de travail temporaire APRÈS les événements de pré-build, obtiennent les sources, puis s'étouffent avec les références NuGet. C'est LE CORRECTIF pour l'automatisation des builds TFS.
CZahrobsky
5

MSBuild 15 a une option / t: restore qui fait cela. il est livré avec Visual Studio 2017.

Si vous souhaitez utiliser ceci, vous devez également utiliser le nouveau PackageReference , ce qui signifie remplacer le packages.configfichier par des éléments comme celui-ci (faites ceci dans * .csproj):

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

Il existe une migration automatisée vers ce format si vous cliquez avec le bouton droit sur `` Références '' (cela peut ne pas s'afficher si vous venez d'ouvrir Visual Studio, reconstruisez ou ouvrez la fenêtre `` Gérer les packages NuGet pour la solution '' et elle commencera à apparaître).

Chris
la source
Vous devez considérer que l'option de restauration de msbuild présente des différences subtiles par rapport à la restauration de nuget - voir github.com/NuGet/Home/issues/7651#issuecomment-500842049 par exemple.
Matthieu
4

Ian Kemp a la réponse (ayez quelques points d'ailleurs ..), c'est simplement ajouter de la viande à l'une de ses étapes.

La raison pour laquelle je me suis retrouvé ici était que les machines de développement se construisaient bien, mais le serveur de compilation ne supprimait tout simplement pas les paquets requis (dossier de paquets vide) et donc la construction échouait. Cependant, la connexion au serveur de build et la création manuelle de la solution ont fonctionné.

Pour effectuer la deuxième des étapes en 3 points d' Ians (exécution de la restauration de nuget ), vous pouvez créer une cible MSBuild exécutant la commande exec pour exécuter la commande de restauration de nuget, comme ci-dessous (dans ce cas, nuget.exe se trouve dans le dossier .nuget, plutôt que sur le chemin), qui peut ensuite être exécuté dans une étape de build TeamCity (autre CI disponible ...) immédiatement avant de construire la solution

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

Pour mémoire, j'avais déjà essayé le type de coureur "nuget installer" mais cette étape était suspendue aux projets Web (fonctionnait pour les projets DLL et Windows)

Fetchez la vache
la source
1
Si vous construisez constamment à partir d'un nouvel ensemble de code (CI), c'est la voie à suivre.
Jahmic
1
J'aime un peu cette approche car elle garantit que chaque solution / projet repose sur la version de nuget avec laquelle il a été créé. En temps voulu, cela peut s'avérer essentiel si vous travaillez dans une entreprise avec d'anciens projets créés à l'aide d'anciennes versions de nuget. Un développeur peut gérer de tels projets sans avoir à se soucier de savoir si le nuget.exe à l'échelle du système va casser des choses parce que chaque projet a sa propre "saveur locale" de nuget.exe. Comme dernier conseil, il convient de noter qu'avec nuget 3.x +, nous pouvons restaurer des packages comme ceci: nuget.exe restore packages.config -PackagesDirectory path \ to \ packages
XDS
1
Le problème que j'ai avec cette approche est que vous devrez modifier tout fichier de projet ultérieur pour ajouter l'étape de restauration. vous pouvez ajouter une activité «InvokeProcess» dans TFS2012 ou une activité «NuGetRestore» dans le modèle de génération TFS2013 pour que cette étape s'exécute sur le serveur de génération. pour InvokeProcess, transmettez l'attribut "SourcesDirectory" en 2012. Dans TFS 2013, remplissez simplement les valeurs requises. il y a beaucoup de blogs sur la façon de procéder.
Neville
3

Notez que si vous utilisez TeamCity comme serveur de génération, vous obtenez une étape «NuGet Installer» que vous pouvez utiliser pour restaurer tous les packages avant l'étape de génération.

Dejan
la source
2

Il existe un fichier packages.config avec le projet, il contient les détails du package.

Il existe également un dossier .nuget qui contient NuGet.exe et NuGet.targets . si l'un des fichiers est manquant, il ne restaurera pas le package manquant et provoquera "vous manque une directive using ou une référence d'assembly?" Erreur

Sumeshk
la source
2
Il n'y a pas de .nugetdossier et ne l'a jamais été. Tous les packages.configfichiers contenus dans les dossiers de projet sont en place.
UserControl
Je pense que NuGet.exe et NuGet.targets restaureront automatiquement tous les packages manquants lors de la construction de l'application et vous avez perdu vos fichiers NuGet.exe et NuGet.targets, cela provoque des erreurs
Sumeshk
Merci quand même - j'apprécie toute aide!
UserControl
le dossier .nuget est un dossier généré par Visual Studio, qui apparaît uniquement lorsque vous activez la restauration automatique de package. Il est utile d'avoir le nuget.exe dans votre référentiel de code, car vous pouvez le référencer dans vos builds, tout comme le nuget.config (surtout si vous avez besoin d'obtenir des packages à partir de plusieurs dépôts).
MytyMyky
2

Parfois, cela se produit lorsque vous avez le dossier du package que vous essayez de restaurer dans le dossier "packages" (c'est-à-dire "Packages / EntityFramework.6.0.0 /" ) mais que les "DLL" ne sont pas à l'intérieur (la plupart du contrôle de version les systèmes ignorent automatiquement les fichiers ".dll"). Cela se produit car avant que NuGet tente de restaurer chaque package, il vérifie si les dossiers existent déjà, donc s'il existe, NuGet suppose que la «dll» se trouve à l'intérieur. Donc, si c'est le problème pour vous, supprimez simplement le dossier que NuGet le restaurera correctement.

fabriciorissetto
la source
1
Pour VS 2015 et TFS, cela vous réparera. Le problème sera une référence non résolue, et souvent le problème est que le package nuget n'est pas restauré car le dossier du package existe déjà dans le dossier packages, mais le package n'a pas été complètement développé correctement. (Par exemple, il manque un dossier lib qui doit contenir un fichier .dll.) Supprimez le dossier entier du package dans les packages, puis cliquez avec le bouton droit au niveau de la solution et choisissez de restaurer les packages.
Greg
1

J'ai eu un problème avec les packages nuget qui n'étaient pas inclus dans une construction nocturne scriptée qui construit le fichier sln à l'aide de devenv.exe.

J'ai suivi les conseils de Microsoft et l'étape clé a été de mettre à jour la configuration NuGet %AppData%/NuGetpour qu'elle contienne:

<configuration>
    <packageRestore>
        <add key="automatic" value="True" />
    </packageRestore>
</configuration>
PaulG
la source
J'ai donc vérifié que lorsque vous modifiez les paramètres dans Visual Studio (la plupart des réponses ici) ... ce qui précède est en fait ce qui est changé. l'autre "clé" est <add key = "enabled" value = "False" />.
grenadeCoder le
0

Dans Visual Studio 2017 - Lorsque vous compilez à l'aide de l'IDE - Il téléchargera tous les packages nuget manquants et les enregistrera dans le dossier "packages".

Mais sur la machine de construction, la compilation a été effectuée à l'aide de msbuild.exe. Dans ce cas, j'ai téléchargé nuget.exe et je suis resté dans le chemin.

Au cours de chaque processus de construction avant d'exécuter msbuild.exe. Il exécutera -> nuget.exe restaure NAME_OF_SLN_File (s'il n'y a qu'un seul fichier .SLN, vous pouvez ignorer ce paramètre)

David
la source
0

Vous pouvez aussi utiliser

Update-Package -reinstall

pour restaurer les packages NuGet sur la console de gestion des packages dans Visual Studio.

MovGP0
la source
Ceci n'est pas une réponse à cette question
TS