Il ripristino automatico del pacchetto NuGet non funziona con MSBuild


111

Sto cercando di creare una soluzione con packagescontenuto mancante (eccetto repositories.configall'interno) con MSBuild 12.0. Mi aspetto che ripristini automaticamente tutti i pacchetti mancanti prima della compilazione, ma non è questo il caso: MsBuild segnala tonnellate di errori:

"ti manca una direttiva using o un riferimento a un assembly?"

NuGet Manager è 2.7 (vedo questo in Visual Studio 2013 sulla scatola). Ho anche provato a passare il EnableNuGetPackageRestore=trueparametro - senza fortuna. Cosa mi sto perdendo?


Stai creando la soluzione in Visual Studio? Inoltre è tutto spuntato nelle Impostazioni di Gestione pacchetti nella sezione Ripristino pacchetto? Non è necessaria la cartella .nuget se si crea in Visual Studio e si usa NuGet 2.7 o versioni successive.
Matt Ward

1
No, sto usando ultima MsBuild ( msdn.microsoft.com/en-us/library/hh162058.aspx versione) da linea di comando. Aggiornato Nuget da VS a 2.8 - senza fortuna.
UserControl

3
MSBuild da solo non verrà ripristinato e nemmeno il componente aggiuntivo VS. È necessario abilitare il ripristino del pacchetto come ha detto @KMoraz, quindi come ha detto Sumeshk viene visualizzata la cartella .nuget ei pacchetti possono essere ripristinati. Assicurati di archiviare .nuget nel controllo del codice sorgente.
Lex Li

Risposte:


36

AGGIORNATO con l'ultima documentazione ufficiale di NuGet a partire dalla v3.3.0

Approcci al ripristino dei pacchetti

NuGet offre tre approcci all'uso del ripristino del pacchetto .


Il ripristino automatico dei pacchetti è l'approccio consigliato dal team di NuGet al ripristino dei pacchetti in Visual Studio ed è stato introdotto in NuGet 2.7. A partire da NuGet 2.7, l'estensione NuGet Visual Studio si integra negli eventi di compilazione di Visual Studio e ripristina i pacchetti mancanti quando inizia una compilazione. Questa funzione è abilitata per impostazione predefinita, ma gli sviluppatori possono disattivarla se lo desiderano.


Ecco come funziona:

  1. Nella compilazione del progetto o della soluzione, Visual Studio genera un evento che indica l'inizio di una compilazione all'interno della soluzione.
  2. NuGet risponde a questo evento e controlla i file packages.config inclusi nella soluzione.
  3. Per ogni file packages.config trovato, i relativi pacchetti vengono enumerati e Checked for esiste nella cartella packages della soluzione.
  4. Eventuali pacchetti mancanti vengono scaricati dalle origini dei pacchetti configurate (e abilitate) dall'utente, rispettando l'ordine delle origini dei pacchetti.
  5. Man mano che i pacchetti vengono scaricati, vengono decompressi nella cartella dei pacchetti della soluzione.

Se hai installato Nuget 2.7+; è importante scegliere un metodo per> gestire il ripristino automatico dei pacchetti in Visual Studio.

Sono disponibili due metodi:

  1. (Nuget 2.7+): Visual Studio -> Strumenti -> Gestione pacchetti -> Impostazioni Gestione pacchetti -> Abilita ripristino pacchetto automatico
  2. (Nuget 2.6 e inferiore) Fare clic con il pulsante destro del mouse su una soluzione e fare clic su "Abilita ripristino pacchetto per questa soluzione".


Il ripristino del pacchetto dalla riga di comando è necessario quando si crea una soluzione dalla riga di comando; è stato introdotto nelle prime versioni di NuGet, ma è stato migliorato in NuGet 2.7.

nuget.exe restore contoso.sln

L' approccio al ripristino del pacchetto integrato in MSBuild è l'implementazione originale del ripristino del pacchetto e sebbene continui a funzionare in molti scenari, non copre l'intero set di scenari affrontati dagli altri due approcci.


63
Questo non è più consigliato da nuget. Vedi i documenti. docs.nuget.org/docs/workflows/…
Owen Johnson

@OwenJohnson, quel documento non è datato che posso vedere e non vedo come dice che non è raccomandato ora? Sono su VS2013 e quel pulsante sembra funzionare bene. Non ho fatto riferimento al problema "Quindi, hai fatto clic su" Abilita ripristino pacchetto Nuget "e ora i tuoi file non vengono compilati. I passaggi per risolverlo sono dolorosi, ma meno dolorosi con questo script." Github.com/owen2/ AutomaticPackageRestoreMigrationScript Forse c'è un altro documento che lo spiega ulteriormente.
AnneTheAgile

5
Il ripristino automatico del pacchetto sostituisce il ripristino integrato di ms-build. Il documento contiene le istruzioni su come eseguire l'aggiornamento. Se non hai problemi con il metodo integrato in msbuild, non devi fare nulla. Nei casi più semplici, funziona, ma se hai server CI, riferimenti a progetti condivisi o altre condizioni, potresti calpestare alcune brutte mine terrestri e avere percorsi di suggerimento errati o altri problemi.
Owen Johnson

1
Usando questa risposta E le istruzioni "rimuovi cose vecchie" "Esecuzione della migrazione" su docs.nuget.org/consume/package-restore/… , sono stato in grado di trovare successo.
granadaCoder

Sembra che le cose siano cambiate di nuovo con NuGet 4 e .net standard.
Owen Johnson,

239

Se utilizzi Visual Studio 2017 o versioniPackageReference successive, fornito con MSBuild 15 o versioni successive, e i file .csproj sono nel nuovo formato , il metodo più semplice consiste nell'usare la nuova Restoredestinazione MSBuild .


Nessuno ha effettivamente risposto alla domanda originale, ovvero "come faccio a ottenere il ripristino automatico dei pacchetti NuGet durante la compilazione dalla riga di comando con MSBuild?" La risposta è: a meno che non si utilizzi l'opzione "Abilita ripristino pacchetto NuGet" (che ora è deprecata secondo questo riferimento ), non è possibile (ma vedere di seguito). Se stai provando ad esempio ad eseguire build automatizzate su un server CI, questo fa schifo.

Tuttavia esiste un modo leggermente indiretto per ottenere il comportamento desiderato:

  1. Scarica l'ultimo eseguibile NuGet da https://dist.nuget.org/win-x86-commandline/latest/nuget.exe e posizionalo da qualche parte nel tuo PATH. (Puoi farlo come passaggio di pre-costruzione.)
  2. Correre nuget restore che scaricherà automaticamente tutti i pacchetti mancanti.
  3. Correre msbuild per costruire la tua soluzione.

A parte: mentre il modo nuovo e consigliato per eseguire il ripristino automatico dei pacchetti comporta meno disordine nel controllo della versione, rende anche impossibile il ripristino del pacchetto dalla riga di comando a meno che non si salti attraverso il cerchio extra del download e dell'esecuzione nuget.exe. Progresso?


Finito con una soluzione simile (ma posizionata nuget.exein / trunk / ext). Un passo avanti - due indietro :(
UserControl

40
Questa dovrebbe essere una risposta corretta, non quella contrassegnata.
Woland

Questo sembra davvero essere un po 'contro intuitivo quando si tratta di questo, ma ottieni davvero più funzionalità per aggiungere pacchetti nuget specifici usando la riga di comando. Questa soluzione ha funzionato per me mentre il ripristino automatico non è riuscito.
TGarrett

2
Stavo usando Jenkins e dovevo farlo, era un semplice passaggio di compilazione prima di chiamare msbuild - Il file batch di Windows era il tipo di passaggio di compilazione e: cmd.exe / c "C: \ Programmi \ nuget \ nuget.exe" ripristino < RelativePathToSln> .sln - Ho fatto il percorso a SLN come abitudine / procedura nel caso in cui non trovasse il file sln.
Steve Radich-BitShop.com

1
Questo approccio ha funzionato per me durante l'impostazione di un ripristino su una build Jenkins. Una chiave importante per me era che NuGet.Config doveva trovarsi nella stessa directory del mio file .SLN. Nessuna combinazione di altre posizioni dei file di configurazione, inclusa la specifica di -ConfigFile sulla riga di comando, funzionerebbe.
Guerry

56

Il ripristino automatico dei pacchetti di Nuget è una funzionalità di Visual Studio (a partire dal 2013), non di MSBuild. Dovrai correrenuget.exe restore se desideri ripristinare i pacchetti dalla riga di comando.

Puoi anche utilizzare la funzione Abilita ripristino pacchetto Nuget, ma questa non è più consigliata dalla gente di Nuget perché apporta modifiche intrusive ai file di progetto e potrebbe causare problemi se costruisci quei progetti in un'altra soluzione.


2
È necessario eseguire "nuget update -self" prima di utilizzare il comando di ripristino se la versione di NuGet non è almeno 2.7. Il mio NuGet era la versione 2.1 e non riconosceva il comando "ripristina" prima dell'aggiornamento.
Teknikaali

2
"causa problemi se costruisci quei progetti in un'altra soluzione" Non ho ancora riscontrato alcun problema e abbiamo 3 soluzioni con dozzine di progetti ciascuna (molti condivisi tra le soluzioni). Forse sono stato fortunato?
Nelson Rothermel

@NelsonRothermel la situazione problematica più notevole che può verificarsi sono i progetti che fanno riferimento a DLL consegnate da nuget alla cartella dei pacchetti di una soluzione esterna, che potrebbe non essere disponibile quando si crea una soluzione.
Owen Johnson

2
@OwenJohnson Abbiamo una cartella dei pacchetti comune per tutte le soluzioni, quindi probabilmente è per questo che non abbiamo riscontrato problemi.
Nelson Rothermel

17

Mi ci è voluto del tempo per capire l'intero quadro e mi piacerebbe condividerlo qui.

Visual Studio ha due approcci per utilizzare il ripristino del pacchetto: ripristino automatico del pacchetto e ripristino del pacchetto integrato in MSBuild. Il "ripristino del pacchetto integrato in MSBuild" ripristina i pacchetti DURANTE il processo di creazione che potrebbero causare problemi in alcuni scenari. Il "Ripristino automatico del pacchetto" è l'approccio consigliato dal team NuGet.

Esistono diversi passaggi per far funzionare il "Ripristino automatico del pacchetto":

  1. In Visual Studio, Strumenti -> Estensioni e aggiornamenti, Aggiorna NuGet se è disponibile una versione più recente (versione 2.7 o successiva)

  2. Se usi TFS, nella cartella .nuget della tua soluzione, rimuovi i file NuGet.exe e NuGet.targes. Quindi modificare NuGet.Config per non archiviare i pacchetti NuGet:

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

    Se in precedenza hai archiviato la cartella dei pacchetti della soluzione su TFS, elimina la cartella e controlla l'eliminazione dell'eliminazione della cartella del pacchetto.

    Se non utilizzi TFS, elimina la cartella .nuget.

  3. In ogni file di progetto (.csproj o .vbproj) nella soluzione, rimuovere la riga che fa riferimento al file NuGet.targets. Il riferimento è simile a questo:

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

    Rimuovi questa riga in ogni file di progetto nella tua soluzione.

  4. Nel menu di Visual Studio, tramite

    Strumenti -> Opzioni -> Gestione pacchetti -> Generale o Strumenti -> Gestione pacchetti NuGet -> Impostazioni di Gestione pacchetti

    abilitare le seguenti due opzioni 1) "Consenti a NuGet di scaricare i pacchetti mancanti" 2) "Verifica automaticamente la presenza di pacchetti mancanti durante la compilazione in Visual Studio"

  5. Testare la configurazione del ripristino del pacchetto seguendo i passaggi seguenti

    • Salva la tua soluzione e chiudi Visual Studio
    • Elimina la cartella dei pacchetti della soluzione
    • Avvia Visual Studio, apri la tua soluzione e ricostruiscila.

1
Uno dei passaggi è rimuovere <Import Project = "$ (MSBuildToolsPath) \ Microsoft.CSharp.targets" />. Perché dovresti farlo?
Sayed Ibrahim Hashimi

3
Penso che ti sbagli che sia nel modello stesso. Senza di essa i tuoi file sorgente non verranno costruiti affatto.
Sayed Ibrahim Hashimi

3
Penso che intendesse nuget.targets invece di Microsoft.CSharp.targets.
Owen Johnson

2
docs.nuget.org/docs/workflows/… <- Ecco i documenti ufficiali di ciò che Ying stava cercando di dire.
Owen Johnson

1
Ying ha ragione ... quello che tutti hanno ignorato è il fatto che le build di Continuous Integration creano il proprio spazio di lavoro temporaneo DOPO gli eventi di pre-compilazione, ottengono le fonti e quindi si soffocano sui riferimenti NuGet. Questa è LA CORREZIONE per l'automazione della compilazione TFS.
CZahrobsky

5

MSBuild 15 ha un'opzione / t: restore che fa questo. viene fornito con Visual Studio 2017.

Se vuoi usarlo, devi anche usare il nuovo PackageReference , il che significa sostituire il packages.configfile con elementi come questo (fallo in * .csproj):

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

Esiste una migrazione automatizzata a questo formato se fai clic con il pulsante destro del mouse su "Riferimenti" (potrebbe non essere visualizzato se hai appena aperto Visual Studio, ricostruito o aperto la finestra "Gestisci pacchetti NuGet per soluzione" e inizierà a comparire).


Devi considerare che l'opzione di ripristino di msbuild presenta sottili differenze rispetto al ripristino di nuget: vedi github.com/NuGet/Home/issues/7651#issuecomment-500842049 per esempio.
Matthieu,

4

Ian Kemp ha la risposta (ho alcuni punti btw ..), questo è semplicemente aggiungere un po 'di carne a uno dei suoi passaggi.

Il motivo per cui sono finito qui era che le macchine di sviluppo stavano costruendo bene, ma il server di compilazione semplicemente non stava estraendo i pacchetti richiesti (cartella dei pacchetti vuota) e quindi la compilazione stava fallendo. Tuttavia, l'accesso al server di compilazione e la creazione manuale della soluzione hanno funzionato.

Per eseguire il secondo dei passaggi in 3 punti di Ians (esecuzione di ripristino nuget ), è possibile creare una destinazione MSBuild eseguendo il comando exec per eseguire il comando di ripristino nuget, come di seguito (in questo caso nuget.exe si trova nella cartella .nuget, anziché sul percorso), che può quindi essere eseguito in una fase di compilazione di TeamCity (altri CI disponibili ...) immediatamente prima di costruire la soluzione

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

Per la cronaca avevo già provato il tipo di runner "nuget installer" ma questo passaggio era sospeso su progetti web (funzionava per progetti DLL e Windows)


1
Se costruisci costantemente da un nuovo set di codice (CI), questa è la strada da percorrere.
Jahmic,

1
Mi piace questo approccio perché garantisce che ogni soluzione / progetto si basi sulla versione di nuget con cui è stato creato. A tempo debito questo può rivelarsi vitale se lavori in un'azienda con vecchi progetti che sono stati creati utilizzando vecchie versioni di nuget. Uno sviluppatore può mantenere tali progetti senza doversi preoccupare se il nuget.exe a livello di sistema interromperà le cose perché ogni progetto ha il suo "sapore locale" di nuget.exe. Come ultimo suggerimento, vale la pena notare che con nuget 3.x + possiamo ripristinare pacchetti in questo modo: nuget.exe restore packages.config -PackagesDirectory path \ to \ packages
XDS

1
Il problema che ho con questo approccio è che dovrai modificare qualsiasi file di progetto successivo per aggiungere il passaggio di ripristino. è possibile aggiungere un'attività "InvokeProcess" in TFS2012 o un'attività "NuGetRestore" nel modello di build TFS2013 per eseguire questo passaggio sul server di build. per InvokeProcess, passare l'attributo "SourcesDirectory" nel 2012. In TFS 2013, è sufficiente inserire i valori come richiesto. ci sono molti blog su come farlo.
Neville

3

Tieni presente che se utilizzi TeamCity come server di compilazione, ottieni un passaggio "NuGet Installer" che puoi utilizzare per ripristinare tutti i pacchetti prima del passaggio di compilazione.


2

C'è un file packages.config con il progetto, contiene i dettagli del pacchetto.

Inoltre è presente una cartella .nuget che contiene NuGet.exe e NuGet.targets . se manca uno qualsiasi dei file, non ripristinerà il pacchetto mancante e causerà "manca una direttiva using o un riferimento all'assembly?" errore


2
Non esiste una .nugetcartella e non lo è mai stata. Tutti i packages.configfile all'interno delle cartelle del progetto sono a posto.
UserControl

Penso che NuGet.exe e NuGet.targets ripristineranno automaticamente tutti i pacchetti mancanti durante la creazione dell'app e hai perso i tuoi file NuGet.exe e NuGet.targets, questo è sì che causa errori
Sumeshk

Grazie comunque - Apprezzo qualsiasi aiuto!
UserControl

la cartella .nuget è una cartella generata da Visual Studio, che appare solo quando si abilita il ripristino automatico del pacchetto. È utile avere nuget.exe nel repository di codice, poiché è possibile farvi riferimento nelle build, così come nuget.config (soprattutto se è necessario ottenere pacchetti da più repository).
MytyMyky

2

A volte ciò si verifica quando hai la cartella del pacchetto che stai tentando di ripristinare all'interno della cartella "packages" (es. "Packages / EntityFramework.6.0.0 /" ) ma le "DLL" non sono al suo interno (la maggior parte del controllo della versione i sistemi ignorano automaticamente i file ".dll"). Ciò si verifica perché prima che NuGet tenti di ripristinare ogni pacchetto, controlla se le cartelle esistono già, quindi, se esiste, NuGet presume che la "dll" sia al suo interno. Quindi, se questo è il problema per te, elimina la cartella che NuGet la ripristinerà correttamente.


1
Per VS 2015 e TFS, questo ti risolverà. Il problema sarà un riferimento non risolto e spesso il problema è che il pacchetto nuget non viene ripristinato perché la cartella del pacchetto esiste già nella cartella dei pacchetti, ma il pacchetto non è stato ancora completamente espanso correttamente. (Ad esempio, manca una cartella lib che dovrebbe contenere un file .dll.) Elimina l'intera cartella per il pacchetto all'interno dei pacchetti, quindi fai clic con il pulsante destro del mouse a livello di soluzione e scegli di ripristinare i pacchetti.
Greg

1

Ho avuto un problema con i pacchetti nuget che non venivano inclusi in una build notturna con script che crea il file sln utilizzando devenv.exe.

Ho seguito il consiglio di Microsoft e il passaggio chiave è stato l'aggiornamento della configurazione di NuGet in %AppData%/NuGetmodo che contenesse:

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

Quindi ho verificato che quando modifichi le impostazioni in Visual Studio (la maggior parte delle risposte qui) ... quanto sopra è in realtà ciò che viene modificato. l'altra "chiave" è <add key = "enabled" value = "False" />.
granadaCoder

0

In Visual Studio 2017 - Quando compili utilizzando IDE - Scarica tutti i pacchetti nuget mancanti e li salva nella cartella "packages".

Ma sulla compilazione della macchina è stata eseguita la compilazione utilizzando msbuild.exe. In quel caso, ho scaricato nuget.exe e ho mantenuto il percorso.

Durante ogni processo di compilazione prima di eseguire msbuild.exe. Verrà eseguito -> nuget.exe ripristina NAME_OF_SLN_File (se c'è un solo file .SLN, puoi ignorare quel parametro)


0

Puoi anche usare

Update-Package -reinstall

per ripristinare i pacchetti NuGet nella console di gestione dei pacchetti in Visual Studio.


Questa non è una risposta a questa domanda
TS
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.