Imposta i file di contenuto su “copia locale: sempre” in un pacchetto nuget

Genero un pacchetto nuget da un progetto con questo comando nell’evento post-build. la variabile %conf% è impostata sulla configurazione corretta (debug o release) e %1 è il nome del progetto (es. “MyCompany.MyProject”).

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

Questo pacchetto è solo per il nostro uso personale, non sarà mai pubblicato su nuget. Finisce nel nostro repository privato.

Nel progetto, c’è un file che è impostato per generate action : content e copy local : always . (Il mio studio visivo è in francese, quindi non sono sicuro al 100% della traduzione). Diamo il nome importantfile.xml .

Nel pacchetto generato, finisco con questa struttura:

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

Che va bene, voglio importantfile.xml da distribuire nel pacchetto, perché, beh, questo file è importante!

Quando installo il pacchetto in un altro progetto, importantfile.xml viene distribuito nella radice del progetto. Va bene. Ma non è impostato per copy local : always .

Ho bisogno di importantfile.xml per essere copy local : always in questo progetto dove installo il mio pacchetto.

Come posso ottenerlo?

Gli appunti :

Posso impostare la copy local : always sul file subito dopo aver installato il pacchetto, non è un grosso problema. Vivrei con esso se gli aggiornamenti successivi del pacchetto lascerebbero questa proprietà così com’è, che non è il caso. Quando si aggiorna il pacchetto, copy local viene reimpostato su never (come indicato qui ).

C’è un file nuspec nella cartella del progetto, eccolo qui:

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

È ansible utilizzare PowerShell e l’hook Install.ps1 fornito da NuGet.

Vedi la documentazione .

Via PowerShell devi “cercare” l’elemento content che include il tuo importantfile.xml in un attributo. Quando lo script lo ha trovato, deve aggiungere Always come elemento figlio.

   Always  

Puoi trovare alcuni snippet di PowerShell qui . .ps1 un’occhiata ai file .ps1 .

Potresti provare quanto segue (non testato). Il file deve essere denominato Install.ps1 e copiato nella cartella degli 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) } } 

Si dovrebbe anche controllare se tutto viene rimosso completamente durante la disinstallazione del pacchetto.

Nota di Jonhhy5

Durante l’aggiornamento del pacchetto tramite pacchetto di update-package , Visual Studio avverte che il progetto viene modificato “fuori dall’ambiente”. Questo è causato da $doc.Save($project.FullName) . Se faccio clic su ricarica prima che il comando sia terminato completamente, a volte causa errori. Il trucco è lasciare la finestra di dialogo fino al termine del processo, quindi ricaricare i progetti.

Invece di usare uno script PowerShell un altro approccio è usare un target MSBuild o un file di oggetti con lo stesso nome dell’ID del pacchetto:

    importantfile.xml Always    

Quindi, nel file nuspec, anziché aggiungere i file richiesti alla directory Content , aggiungerli alla directory Build insieme al file target.

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

Se hai bisogno di contenuti diversi per architetture diverse, puoi aggiungere cartelle di architettura in Build ognuna con il proprio file di destinazione.

Vantaggi dell’utilizzo di un file target sullo script PowerShell con la directory Content NuGet:

  • i file di contenuto richiesti non vengono visualizzati nel progetto in Visual Studio
  • i file di contenuto sono collegati anziché copiati nella directory di ciascun progetto che fa riferimento al pacchetto NuGet (impedendo che vi siano più copie e mantenendo il comportamento uguale a quello degli assembly / librerie dai pacchetti NuGet)
  • Gli script di PowerShell funzionano solo in Visual Studio e non vengono eseguiti quando NuGet viene eseguito dalla riga di comando (build server, altri IDE e altri sistemi operativi), questo approccio funzionerà ovunque
  • Gli script di installazione di PowerShell non sono supportati in NuGet 3.x project.json system .

quindi so che voi ragazzi avete trovato una soluzione funzionante, ma non ha funzionato per me, quindi condividerò ciò che ho estratto dal pacchetto NuGet di NLog.config install.ps1

NOTA: questo non è il mio codice, questo è il contenuto di install.ps1 dal pacchetto nuget di NLog.config che condivide solo la conoscenza.

sembra un po ‘più semplice per me e spero solo di aiutare gli altri che probabilmente inciamperanno su questo.

qui puoi trovare i valori int accettati per BuildAction e i valori accettati per 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 

Ho fatto questo che copia i file dalla mia cartella di costruzione alla cartella di output (bin / debug o bin / release). Funziona come un fascino per me.

File NUSPEC:

         

MyProject.targets

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

Ho scritto un piccolo strumento chiamato NuGetLib per aggiungere automaticamente i file al pacchetto nuget dopo la compilazione.

  1. creare una cartella di tools con lo script Install.ps1
  2. crea il tuo nugetPackage
  3. aggiungi la cartella degli strumenti al nugetPackage

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