Definir arquivos de conteúdo para “copiar local: sempre” em um pacote nuget

Eu gero um pacote nuget de um projeto com este comando no evento pós-compilation. a variável %conf% é definida para a configuração correta (debugging ou liberação) e %1 é o nome do projeto (por exemplo, “MyCompany.MyProject”).

 nuget pack -Prop Configuration=%conf% "%1.csproj" -exclude *.sql -IncludeReferencedProjects 

Este pacote é apenas para uso próprio, nunca será publicado no nuget. Ele termina no nosso repository privado.

No projeto, há um arquivo que é configurado para generate action : content e copy local : always . (Meu visual studio é em francês, então eu não tenho 100% de certeza da tradução). Vamos chamá-lo importantfile.xml .

No pacote gerado, acabo com essa estrutura:

 - content - importantfile.xml - lib -net45 (.NetFramework,Version=v4.5) -MyCompany.MyProject.dll 

O que é bom, eu quero importantfile.xml para ser implantado no pacote, porque, bem, este arquivo é importante!

Quando instalo o pacote em outro projeto, importantfile.xml é implantado na raiz do projeto. Isso está ok. Mas não está definido para copy local : always .

Eu preciso importantfile.xml para ser copy local : always neste projeto onde eu instalo meu pacote.

Como posso conseguir isso?

Notas :

Eu posso definir copy local : always no arquivo logo após a instalação do pacote, isso não é grande coisa. Eu viveria com isso se atualizações posteriores do pacote deixassem essa propriedade como está, o que não é o caso. Ao atualizar o pacote, a copy local é redefinida para never (conforme indicado aqui ).

Há um arquivo nuspec na pasta do projeto, aqui está:

    $id$ $version$ $title$ $author$ $author$ false $description$ Copyright 2014 some random tags   

Você pode usar o PowerShell e o gancho Install.ps1 fornecidos pelo NuGet.

Veja a documentação .

Por meio do PowerShell, você precisa pesquisar o elemento de conteúdo que inclui seu importantfile.xml em um atributo. Quando o script o encontrou, ele deve include Always como um elemento filho.

   Always  

Você pode encontrar alguns trechos do PowerShell aqui . Basta dar uma olhada nos arquivos .ps1 .

Você poderia tentar o seguinte (não testado). O arquivo deve ser nomeado como Install.ps1 e copiado para a pasta de tools :

 param($installPath, $toolsPath, $package, $project) # Load project XML. $doc = New-Object System.Xml.XmlDocument $doc.Load($project.FullName) $namespace = 'http://schemas.microsoft.com/developer/msbuild/2003' # Find the node containing the file. The tag "Content" may be replace by "None" depending of the case, check your .csproj file. $xmlNode = Select-Xml "//msb:Project/msb:ItemGroup/msb:Content[@Include='importantfile.xml']" $doc -Namespace @{msb = $namespace} #check if the node exists. if($xmlNode -ne $null) { $nodeName = "CopyToOutputDirectory" #Check if the property already exists, just in case. $property = $xmlNode.Node.SelectSingleNode($nodeName) if($property -eq $null) { $property = $doc.CreateElement($nodeName, $namespace) $property.AppendChild($doc.CreateTextNode("Always")) $xmlNode.Node.AppendChild($property) # Save changes. $doc.Save($project.FullName) } } 

Você também deve verificar se tudo foi removido completamente ao desinstalar o pacote.

Nota por Jonhhy5

Ao atualizar o pacote via update-package , o Visual Studio avisa que o projeto está modificado “fora do ambiente”. Isso é causado por $doc.Save($project.FullName) . Se eu clicar em recarregar antes que o comando seja totalmente terminado, às vezes causará erros. O truque é deixar a checkbox de diálogo lá até o processo terminar e, em seguida, recarregar os projetos.

Em vez de usar um script do PowerShell, outra abordagem é usar um arquivo de propósitos ou destinos do MSBuild com o mesmo nome que o ID do pacote:

    importantfile.xml Always    

No arquivo nuspec, em vez de include os arquivos necessários no diretório Content , inclua-os no diretório Build junto com o arquivo de destinos.

  • Construir
    • importantfile.xml
    • MyPackage.targets
  • lib
    • net45
      • MyAssembly.dll

Se você precisar de conteúdo diferente para arquiteturas diferentes, poderá adicionar pastas de arquitetura em Build também, cada uma com seu próprio arquivo de destinos.

Benefícios de usar um arquivo de destinos sobre o script do PowerShell com o diretório de Content NuGet:

  • os arquivos de conteúdo necessários não são mostrados no projeto no Visual Studio
  • os arquivos de conteúdo são vinculados em vez de serem copiados no diretório de cada projeto que faz referência ao pacote NuGet (impedindo que haja várias cópias e mantendo o comportamento igual ao dos assemblies / bibliotecas dos pacotes NuGet)
  • Os scripts do PowerShell funcionam somente no Visual Studio e não são executados quando o NuGet é executado a partir da linha de comando (servidores de compilation, outros IDEs e outros sistemas operacionais), essa abordagem funcionará em todos os lugares
  • Os scripts de instalação do PowerShell não são suportados no sistema NuGet 3.x project.json .

então eu sei que vocês tem uma solução de trabalho para isso, mas não funcionou para mim, então eu vou compartilhar o que eu tirei do pacote NLG.config NuGet install.ps1

NOTA: este não é o meu código, este é o conteúdo do install.ps1 do pacote nuget NLog.config que apenas compartilha o conhecimento.

parece um pouco mais direto para mim e apenas esperando ajudar os outros que provavelmente tropeçarão nisso.

Você pode encontrar aqui os valores int aceitos para BuildAction e os valores aceitos para CopyToOutputDirectory.

 param($installPath, $toolsPath, $package, $project) $configItem = $project.ProjectItems.Item("NLog.config") # set 'Copy To Output Directory' to 'Copy if newer' $copyToOutput = $configItem.Properties.Item("CopyToOutputDirectory") # Copy Always Always copyToOutput.Value = 1 # Copy if Newer copyToOutput.Value = 2 $copyToOutput.Value = 2 # set 'Build Action' to 'Content' $buildAction = $configItem.Properties.Item("BuildAction") $buildAction.Value = 2 

Eu fiz isso que copia arquivos da minha pasta de compilation para a pasta de saída (bin / debug ou bin / release). Funciona como um encanto para mim.

Arquivo Nuspec:

         

MyProject.targets

     %(RecursiveDir)%(FileName)%(Extension) PreserveNewest    

Eu escrevi uma pequena ferramenta chamada NuGetLib para adicionar arquivos automaticamente ao pacote nuget após a compilation.

  1. crie uma pasta de tools com seu script Install.ps1
  2. construa seu nugetPackage
  3. adicione a pasta de ferramentas ao nugetPackage criado

https://stackoverflow.com/a/47134733/6229375

Intereting Posts