Question Définir les fichiers de contenu sur "copier local: toujours" dans un paquet nuget


Je génère un package nuget à partir d'un projet avec cette commande dans l'événement de post-construction. la variable %conf% est configuré à la bonne configuration (débogage ou version) et %1 est le nom du projet (par exemple "MyCompany.MyProject").

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

Ce paquet est pour notre propre usage seulement, il ne sera jamais publié sur nuget. Il se termine dans notre référentiel privé.

Dans le projet, un fichier est défini sur generate action : content et copy local : always. (Mon studio visuel est en français, donc je ne suis pas sûr à 100% de la traduction). Nommons-le importantfile.xml.

Dans le package généré, je me retrouve avec cette structure:

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

Ce qui est bien, je veux importantfile.xml à déployer dans le package, car, bien, ce fichier est important!

Lorsque j'installe le package dans un autre projet, importantfile.xml est déployé à la racine du projet. C'est bon. Mais il n'est pas réglé sur copy local : always.

j'ai besoin importantfile.xml être copy local : always dans ce projet où j'installe mon paquet. 

Comment puis-je y arriver?

Remarques :

je pouvez ensemble copy local : always sur le fichier juste après l'installation du paquet, ce n'est pas grave. Je vivrais avec elle si les mises à jour ultérieures du paquet laisseraient cette propriété telle quelle, ce qui n'est pas le cas. Lors de la mise à jour du paquet, copy local est réinstallé à never (comme indiqué ici).

Il y a un fichier nuspec dans le dossier du projet, le voici:

<?xml version="1.0"?>
<package >
  <metadata>
    <id>$id$</id>
    <version>$version$</version>
    <title>$title$</title>
    <authors>$author$</authors>
    <owners>$author$</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>$description$</description>
    <copyright>Copyright 2014</copyright>
    <tags>some random tags</tags>
  </metadata>
</package>

51
2018-01-15 17:08


origine


Réponses:


Vous pouvez utiliser PowerShell et le Install.ps1 crochet fourni par NuGet.

Voir le Documentation.

Via PowerShell, vous devez rechercher l'élément de contenu qui inclut votre importantfile.xml dans un attribut. Lorsque le script l'a trouvé, il doit ajouter <CopyToOutputDirectory>Always</CopyToOutputDirectory> comme élément enfant.

    <Content Include="importantfile.xml">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>

Vous pouvez trouver des extraits de PowerShell ici. Il suffit de regarder le .ps1 des dossiers.

Vous pouvez essayer ce qui suit (non testé). Le fichier doit être nommé Install.ps1 et copié dans le tools dossier:

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)
    }
}

Vous devez également vérifier si tout est complètement supprimé lors de la désinstallation du package.

Note de Jonhhy5

Lors de la mise à jour du paquet via update-package, Visual Studio avertit que le projet est modifié "en dehors de l'environnement". C'est causé par $doc.Save($project.FullName). Si je clique sur recharger avant la commande est complètement terminée, cela provoque parfois des erreurs. L'astuce consiste à laisser la boîte de dialogue là jusqu'à ce que le processus se termine, et puis recharger les projets.


2
2018-01-16 12:14



Au lieu d’utiliser un script PowerShell, une autre approche consiste à utiliser un script Cibles MSBuild ou fichier props avec le même nom que l'identifiant du package:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <None Include="$(MSBuildThisFileDirectory)importantfile.xml">
      <Link>importantfile.xml</Link>
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
  </ItemGroup>
</Project>

Dans le fichier nuspec, au lieu d'ajouter les fichiers requis à la Content répertoire, ajoutez-les à la Build répertoire avec le fichier de cibles.

  • Construire
    • fichierfichier.xml
    • MyPackage.targets
  • lib
    • net45
      • MyAssembly.dll

Si vous avez besoin de contenu différent pour différentes architectures, vous pouvez ajouter des dossiers d’architecture sous Buildchacun avec son propre fichier de cibles.

Avantages de l'utilisation d'un fichier cible par rapport au script PowerShell avec NuGet Content annuaire:

  • les fichiers de contenu requis ne sont pas affichés dans le projet dans Visual Studio
  • les fichiers de contenu sont liés au répertoire plutôt que copiés dans le répertoire de chaque projet qui fait référence au package NuGet (empêchant qu'il y ait plusieurs copies et conservant le même comportement que pour les assemblys / bibliothèques des packages NuGet)
  • Les scripts PowerShell ne fonctionnent que dans Visual Studio et ne sont pas exécutés lorsque NuGet est exécuté depuis la ligne de commande (construire des serveurs, d'autres IDE et d'autres systèmes d'exploitation), cette approche fonctionnera partout
  • Les scripts d’installation de PowerShell sont non pris en charge dans le système project.json NuGet 3.x.

113
2018-05-22 01:10



donc je sais que vous avez une solution de travail à cela, mais cela n'a pas fonctionné pour moi donc je vais partager ce que j'ai retiré de la Package NLog.config NuGet install.ps1

NOTE: ce n'est pas mon code, c'est le contenu du fichier install.ps1 de   le package nuget NLog.config ne partageant que les connaissances.

semble un peu plus simple pour moi et j'espère juste aider les autres qui vont probablement tomber sur cela.

vous pouvez trouver les valeurs int acceptées pour BuildAction ici et les valeurs acceptées pour CopyToOutputDirectory ici.

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

35
2017-09-30 20:34



Je l'ai fait ce qui copie les fichiers de mon dossier de construction dans le dossier de sortie (bin / debug ou bin / release). Fonctionne comme un charme pour moi.

Fichier Nuspec:

<package>
  <files>
    <file src="\bin\Release\*.dll" target="lib" />
    <file src="\bin\Release\x64\*.dll" target="build\x64" />
    <file src="\bin\Release\x86\*.dll" target="build\x86" />
    <file src="MyProject.targets" target="build\" />    
  </files>
</package>

MyProject.targets

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <NativeLibs Include="$(MSBuildThisFileDirectory)**\*.dll" />
    <None Include="@(NativeLibs)">
      <Link>%(RecursiveDir)%(FileName)%(Extension)</Link>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>
</Project>

4
2017-07-03 07:28



J'ai écrit un petit outil appelé NuGetLib ajouter automatiquement des fichiers au package nuget après la construction.

  1. créer un tools dossier avec votre Install.ps1 scénario
  2. construisez votre nugetPackage
  3. ajouter le dossier outils au construit nugetPackage

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


0
2017-11-06 10:30