A restauração automática do pacote NuGet não funciona com o MSBuild

111

Estou tentando construir uma solução com packagesfalta de conteúdo (excetorepositories.config dentro) com o MSBuild 12.0. Espero que ele restaure automaticamente todos os pacotes ausentes antes de compilar, mas este não é o caso - o MsBuild relata toneladas de erros:

"está faltando uma diretiva using ou uma referência do assembly?"

NuGet Manager é 2.7 (vejo isso no Visual Studio 2013 sobre a caixa). Eu até tentei passar o EnableNuGetPackageRestore=trueparâmetro - sem sorte. o que estou perdendo?

UserControl
fonte
Você está construindo a solução no Visual Studio? Além disso, tudo está marcado nas Configurações do Gerenciador de Pacotes na seção Restauração de Pacotes? Você não precisa da pasta .nuget se estiver criando dentro do Visual Studio e usando NuGet 2.7 ou superior.
Matt Ward
1
Não, estou usando a versão mais recente do MsBuild ( msdn.microsoft.com/en-us/library/hh162058.aspx ) da linha de comando. Nuget atualizado de dentro do VS para 2.8 - sem sorte.
UserControl
3
O MSBuild sozinho não restaurará e o suplemento do VS também. Você precisa habilitar a restauração de pacote como @KMoraz disse, e então como Sumeshk disse a pasta .nuget aparece e os pacotes podem ser restaurados. Certifique-se de verificar .nuget no controle de origem.
Lex Li

Respostas:

36

ATUALIZADO com a documentação oficial do NuGet mais recente a partir da v3.3.0

Abordagens de restauração de pacote

O NuGet oferece três abordagens para usar a restauração de pacote .


A Restauração automática de pacotes é a abordagem recomendada pela equipe do NuGet para a restauração de pacotes no Visual Studio e foi introduzida no NuGet 2.7. Começando com NuGet 2.7, a extensão NuGet Visual Studio se integra aos eventos de compilação do Visual Studio e restaura pacotes ausentes quando uma compilação começa. Esse recurso é habilitado por padrão, mas os desenvolvedores podem cancelar, se desejarem.


Funciona assim:

  1. No projeto ou versão da solução, o Visual Studio gera um evento de que uma versão está começando na solução.
  2. O NuGet responde a esse evento e verifica os arquivos packages.config incluídos na solução.
  3. Para cada arquivo packages.config encontrado, seus pacotes são enumerados e Verificados se existem na pasta de pacotes da solução.
  4. Quaisquer pacotes ausentes são baixados das fontes de pacote configuradas (e habilitadas) do usuário, respeitando a ordem das fontes de pacote.
  5. Conforme os pacotes são baixados, eles são descompactados na pasta de pacotes da solução.

Se você tiver o Nuget 2.7+ instalado; é importante escolher um método para> gerenciar a restauração automática de pacotes no Visual Studio.

Dois métodos estão disponíveis:

  1. (Nuget 2.7+): Visual Studio -> Ferramentas -> Gerenciador de Pacotes -> Configurações do Gerenciador de Pacotes -> Habilitar Restauração Automática de Pacotes
  2. (Nuget 2.6 e abaixo) Clique com o botão direito em uma solução e clique em "Habilitar Restauração de Pacote para esta solução".


A restauração do pacote da linha de comando é necessária ao criar uma solução a partir da linha de comando; foi introduzido nas primeiras versões do NuGet, mas foi aprimorado no NuGet 2.7.

nuget.exe restore contoso.sln

A abordagem de restauração de pacote integrada ao MSBuild é a implementação original da Restauração de pacote e, embora continue a funcionar em muitos cenários, não cobre o conjunto completo de cenários endereçados pelas outras duas abordagens.

KMoraz
fonte
63
Isso não é mais recomendado pela nuget. Veja a documentação. docs.nuget.org/docs/workflows/…
Owen Johnson
@OwenJohnson, esse documento não é datado que eu posso ver e não vejo como diz que não é recomendado agora? Estou no VS2013 e esse botão parece funcionar bem. Não tive o problema referenciado, "Então, você clicou em" Habilitar Restauração do Pacote Nuget "e agora seu material não é compilado. As etapas para corrigi-lo são dolorosas, mas menos dolorosas com este script." Github.com/owen2/ AutomaticPackageRestoreMigrationScript Talvez haja outro documento que explique isso melhor.
AnneTheAgile
5
A restauração automática do pacote substitui a restauração integrada do ms-build. O documento contém as instruções sobre como fazer o upgrade. Se você não está tendo problemas com o método integrado ao msbuild, não precisa fazer nada. Nos casos mais simples, funciona, mas se você tiver servidores de CI, referências de projeto compartilhadas ou algumas outras condições, poderá pisar em algumas minas terrestres desagradáveis ​​e ter hintpaths incorretos ou outros problemas.
Owen Johnson
1
Usando esta resposta E seguindo as instruções de "remover coisas antigas" "Executando a migração" em docs.nuget.org/consume/package-restore/… , consegui obter sucesso.
granadaCoder
Parece que as coisas mudaram novamente com o NuGet 4 e o padrão .net.
Owen Johnson
239

Se você estiver usando o Visual Studio 2017 ou posterior, que vem com o MSBuild 15 ou posterior, e seus arquivos .csproj estiverem no novo PackageReferenceformato , o método mais simples é usar o novo Restoredestino MSBuild .


Ninguém realmente respondeu à pergunta original, que é "como faço para que os pacotes NuGet sejam restaurados automaticamente ao compilar a partir da linha de comando com o MSBuild?" A resposta é: a menos que você esteja usando a opção "Habilitar restauração de pacote NuGet" (que agora está obsoleta de acordo com esta referência ), você não pode (mas veja abaixo). Se você está tentando fazer, por exemplo, compilações automatizadas em um servidor de CI, isso é uma droga.

No entanto, há uma maneira um pouco indireta de obter o comportamento desejado:

  1. Baixe o executável NuGet mais recente em https://dist.nuget.org/win-x86-commandline/latest/nuget.exe e coloque-o em algum lugar em seu PATH. (Você pode fazer isso como uma etapa de pré-construção.)
  2. Execute o nuget restorequal fará o download automático de todos os pacotes ausentes.
  3. Execute msbuildpara construir sua solução.

Afora isso: embora a maneira nova e recomendada de fazer a restauração automática de pacotes envolva menos desordem em seu controle de versão, ela também torna a restauração de pacotes de linha de comando impossível, a menos que você pule o aro extra de baixar e executar nuget.exe. Progresso?

Ian Kemp
fonte
Terminou com solução semelhante (mas colocado nuget.exeem / trunk / ext). Um passo à frente - dois passos atrás :(
UserControl
40
Esta deve ser uma resposta correta, não aquela marcada.
Woland
Isso realmente parece um pouco contra-intuitivo quando se trata disso, mas você realmente obtém mais funcionalidades para adicionar pacotes nuget específicos usando a linha de comando. Essa solução funcionou para mim enquanto a restauração automática falhou.
TGarrett
2
Eu estava usando o Jenkins e tive que fazer isso, era uma etapa de compilação simples antes de chamar msbuild - o arquivo em lote do Windows era o tipo de etapa de compilação e: cmd.exe / c "C: \ Arquivos de programas \ nuget \ nuget.exe" restaurar < RelativePathToSln> .sln - Fiz o caminho para SLN como um hábito / procedimento apenas no caso de não encontrar o arquivo sln.
Steve Radich-BitShop.com
1
Essa abordagem funcionou para mim ao configurar uma restauração em uma construção do Jenkins. Uma chave importante para mim era que o NuGet.Config tinha que estar no mesmo diretório do meu arquivo .SLN. Nenhuma combinação de outros locais de arquivo de configuração, incluindo a especificação de -ConfigFile na linha de comando, funcionaria.
Guerry
56

A Restauração Automática de Pacote do Nuget é um recurso do Visual Studio (começando em 2013), não do MSBuild. Você terá que executar nuget.exe restorese quiser restaurar pacotes da linha de comando.

Você também pode usar o recurso Habilitar restauração do pacote Nuget, mas isso não é mais recomendado pelo pessoal do nuget porque faz alterações intrusivas nos arquivos do projeto e pode causar problemas se você construir esses projetos em outra solução.

Owen Johnson
fonte
2
Você precisa executar "nuget update -self" antes de usar o comando restore se sua versão do NuGet não for pelo menos 2.7. Meu NuGet tinha a versão 2.1 e não reconhecia o comando "restaurar" antes de atualizar.
Teknikaali
2
"causa problemas se você construir esses projetos em outra solução" Não encontrei nenhum problema ainda e temos 3 soluções com dezenas de projetos cada (muitos compartilhados entre as soluções). Talvez eu tenha tido sorte?
Nelson Rothermel
@NelsonRothermel a situação problemática mais notável que pode acontecer são projetos que fazem referência a dlls entregues por nuget para uma pasta de pacotes de solução externa, que pode não estar disponível quando você constrói uma solução.
Owen Johnson
2
@OwenJohnson Temos uma pasta de pacote comum para todas as soluções, então é provavelmente por isso que não tivemos problemas.
Nelson Rothermel de
17

Levei algum tempo para descobrir a imagem completa e gostaria de compartilhar aqui.

O Visual Studio tem duas abordagens para usar a restauração de pacote: Restauração automática de pacote e restauração de pacote integrada ao MSBuild. O 'MSBuild-Integrated Package Restore' restaura pacotes DURANTE o processo de construção que pode causar problemas em alguns cenários. A 'Restauração automática de pacote' é a abordagem recomendada pela equipe do NuGet.

Existem várias etapas para fazer a 'Restauração Automática de Pacote' funcionar:

  1. No Visual Studio, Ferramentas -> Extensões e atualizações, Atualizar NuGet se houver uma versão mais recente (versão 2.7 ou posterior)

  2. Se você usar o TFS, na pasta .nuget da solução, remova os arquivos NuGet.exe e NuGet.targes. Em seguida, edite NuGet.Config para não fazer check-in de pacotes NuGet:

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

    Se você fez check-in da pasta de pacotes da solução no TFS antes, exclua a pasta e faça check-in da exclusão da exclusão da pasta do pacote.

    Se você não usa o TFS, exclua a pasta .nuget.

  3. Em cada arquivo de projeto (.csproj ou .vbproj) em sua solução, remova a linha que faz referência ao arquivo NuGet.targets. A referência se parece com isto:

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

    Remova esta linha em cada arquivo de projeto em sua solução.

  4. No menu do Visual Studio, por meio de

    Ferramentas -> Opções -> Gerenciador de pacotes -> Geral ou Ferramentas -> Gerenciador de pacotes NuGet -> Configurações do gerenciador de pacotes

    habilite as duas opções a seguir 1) 'Permitir que o NuGet baixe pacotes ausentes' 2) 'Verificar automaticamente se há pacotes ausentes durante a compilação no Visual Studio'

  5. Teste a configuração de restauração de seu pacote seguindo as seguintes etapas

    • Salve sua solução e feche o Visual Studio
    • Exclua a pasta de pacotes da sua solução
    • Inicie o Visual Studio, abra sua solução e reconstrua-a.
Ying
fonte
1
Uma das etapas é remover <Import Project = "$ (MSBuildToolsPath) \ Microsoft.CSharp.targets" />. Por que você faria isso?
Sayed Ibrahim Hashimi
3
Eu acho que você está enganado que está no próprio modelo. Sem ele, seus arquivos de origem não serão compilados.
Sayed Ibrahim Hashimi
3
Acho que ele quis dizer nuget.targets em vez de Microsoft.CSharp.targets.
Owen Johnson,
2
docs.nuget.org/docs/workflows/… <- Aqui estão os documentos oficiais do que Ying estava tentando dizer.
Owen Johnson
1
Ying está certo ... o que todos ignoraram é o fato de que as construções de integração contínua criam seu próprio espaço de trabalho temporário APÓS os eventos de pré-construção, obtêm os códigos-fonte e, em seguida, bloqueiam as referências do NuGet. Esta é a CORREÇÃO para a automação de compilação do TFS.
CZahrobsky
5

MSBuild 15 tem a / t: opção de restauração que faz isso. ele vem com o Visual Studio 2017.

Se quiser usar isso, você também terá que usar o novo PackageReference , o que significa substituir o packages.configarquivo por elementos como este (faça isso em * .csproj):

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

Há uma migração automática para este formato se você clicar com o botão direito em 'Referências' (pode não aparecer se você apenas abrir o Visual Studio, reconstruir ou abrir a janela 'Gerenciar pacotes NuGet para solução' e ela começará a aparecer).

Chris
fonte
Você deve considerar que a opção de restauração do msbuild tem diferenças sutis da restauração do nuget - consulte github.com/NuGet/Home/issues/7651#issuecomment-500842049 por exemplo.
Matthieu de
4

Ian Kemp tem a resposta (tem alguns pontos aliás ..), isso é simplesmente adicionar um pouco de carne a um de seus passos.

A razão pela qual acabei aqui foi que as máquinas de desenvolvimento estavam construindo bem, mas o servidor de construção simplesmente não estava baixando os pacotes necessários (pasta de pacotes vazia) e, portanto, a construção estava falhando. No entanto, fazer logon no servidor de compilação e compilar manualmente a solução funcionou.

Para cumprir a segunda das etapas de 3 pontos de Ians (executando a restauração do nuget ), você pode criar um destino MSBuild executando o comando exec para executar o comando de restauração do nuget, como abaixo (neste caso, nuget.exe está na pasta .nuget, em vez de no caminho), que pode então ser executado em uma etapa de construção do TeamCity (outro CI disponível ...) imediatamente antes de construir a solução

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

Para o registro, eu já tentei o tipo de execução "nuget installer", mas esta etapa estava travando em projetos da web (funcionou para projetos de DLL e Windows)

Fetchez la vache
fonte
1
Se você está constantemente construindo a partir de um novo conjunto de códigos (CI), este é o caminho a seguir.
Jahmic de
1
Eu meio que gosto dessa abordagem porque ela garante que cada solução / projeto dependa da versão do nuget com a qual foi criado. No devido tempo, isso pode ser vital se você trabalhar em uma empresa com projetos antigos que foram criados com versões antigas do nuget. Um desenvolvedor pode manter esses projetos sem ter que se preocupar se o nuget.exe de todo o sistema danificará as coisas, porque cada projeto tem seu próprio "sabor local" de nuget.exe. Como última dica, vale a pena observar que com o nuget 3.x + podemos restaurar pacotes como: nuget.exe restore packages.config -PackagesDirectory path \ to \ packages
XDS
1
O problema que tenho com essa abordagem é que você precisará editar qualquer arquivo de projeto subsequente para adicionar a etapa de restauração. você pode adicionar uma atividade "InvokeProcess" no TFS2012 ou uma atividade "NuGetRestore" no modelo de construção TFS2013 para que esta etapa seja executada no servidor de construção. para InvokeProcess, passe o atributo "SourcesDirectory" em 2012. No TFS 2013, basta preencher os valores conforme necessário. há muitos blogs sobre como fazer isso.
Neville
3

Observe que se você estiver usando o TeamCity como um servidor de compilação, receberá uma etapa de "Instalador NuGet" que pode ser usada para restaurar todos os pacotes antes da etapa de compilação.

Dejan
fonte
2

Existe um packages.config arquivo com o projeto, ele contém os detalhes do pacote.

Também há uma pasta .nuget que contém NuGet.exe e NuGet.targets . se algum dos arquivos estiver faltando, ele não restaurará o pacote ausente e causará "está faltando uma diretiva de uso ou uma referência de assembly?" erro

Sumeshk
fonte
2
Não existe .nugetpasta e nunca existiu. Todos os packages.configarquivos nas pastas do projeto estão no lugar.
UserControl
Eu acho que NuGet.exe e NuGet.targets irão restaurar automaticamente todos os pacotes ausentes durante a construção do aplicativo e você perdeu seus arquivos NuGet.exe e NuGet.targets, isso é o que causa erros
Sumeshk
Obrigado de qualquer maneira -Agradeço qualquer ajuda!
UserControl
a pasta .nuget é uma pasta gerada pelo Visual Studio, que aparece apenas quando você habilita a restauração automática de pacote. É útil ter o nuget.exe em seu repositório de código, pois você pode referenciá-lo em suas compilações, assim como o nuget.config (especialmente se você precisar obter pacotes de vários repositórios).
MytyMyky
2

Às vezes, isso ocorre quando você tem a pasta do pacote que está tentando restaurar dentro da pasta "packages" (ou seja, "Packages / EntityFramework.6.0.0 /" ), mas as "DLLs" não estão dentro dela (a maior parte do controle de versão sistemas ignoram automaticamente os arquivos ".dll"). Isso ocorre porque antes do NuGet tentar restaurar cada pacote, ele verifica se as pastas já existem; portanto, se existirem, o NuGet presume que a "dll" está dentro dele. Portanto, se este for o problema para você, basta excluir a pasta que o NuGet irá restaurá-la corretamente.

fabriciorissetto
fonte
1
Para VS 2015 e TFS, isso vai consertar você. O problema será uma referência não resolvida e, frequentemente, o problema é que o pacote nuget não está sendo restaurado porque a pasta para o pacote já existe na pasta de pacotes, mas ainda assim o pacote não foi totalmente expandido de forma adequada. (Por exemplo, falta uma pasta lib que deve conter um .dll.) Exclua a pasta inteira para o pacote dentro dos pacotes e, em seguida, clique com o botão direito no nível da solução e escolha restaurar os pacotes.
Greg
1

Tive um problema com os pacotes nuget não sendo incluídos em uma compilação noturna com script que cria o arquivo sln usando devenv.exe.

Segui o conselho da Microsoft e a etapa principal foi atualizar a configuração do NuGet %AppData%/NuGetpara que contivesse:

<configuration>
    <packageRestore>
        <add key="automatic" value="True" />
    </packageRestore>
</configuration>
PaulG
fonte
Portanto, verifiquei que quando você altera as configurações no Visual Studio (a maioria das respostas aqui) ... o que está acima é realmente o que muda. a outra "chave" é <add key = "enabled" value = "False" />.
granadaCoder
0

No Visual Studio 2017 - quando você compila usando IDE - ele irá baixar todos os pacotes nuget ausentes e salvar na pasta "pacotes".

Mas na compilação da máquina de construção foi feita usando msbuild.exe. Nesse caso, baixei o nuget.exe e mantive o caminho.

Durante cada processo de compilação, antes de executar msbuild.exe. Ele irá executar -> nuget.exe restaurar NAME_OF_SLN_File (se houver apenas um arquivo .SLN, você pode ignorar esse parâmetro)

David
fonte
0

Você também pode usar

Update-Package -reinstall

para restaurar os pacotes NuGet no Console de gerenciamento de pacotes no Visual Studio.

MovGP0
fonte
Esta não é uma resposta a esta pergunta
TS