webentwicklung-frage-antwort-db.com.de

Setzen Sie Inhaltsdateien in einem Nuget-Paket auf "local: always kopieren"

Mit diesem Befehl generiere ich im Post-Build-Ereignis ein Nuget-Paket aus einem Projekt. Die Variable %conf% ist auf die richtige Konfiguration (Debug oder Release) eingestellt, und %1 ist der Projektname (z. B. "MyCompany.MyProject").

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

Dieses Paket ist nur für unseren eigenen Gebrauch bestimmt und wird niemals auf Nuget veröffentlicht. Es endet in unserem privaten Repository.

In dem Projekt befindet sich eine Datei, die auf generate action : content und copy local : always festgelegt ist. (Mein visuelles Studio ist auf Französisch, daher bin ich mir der Übersetzung nicht 100% sicher). Nennen wir es importantfile.xml.

Im generierten Paket erhalte ich folgende Struktur:

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

Was in Ordnung ist, ich möchte, dass importantfile.xml im Paket bereitgestellt wird, denn nun, diese Datei ist wichtig!

Wenn ich das Paket in einem anderen Projekt installiere, wird importantfile.xml im Stammverzeichnis des Projekts bereitgestellt. Kein Problem. Es ist jedoch nicht auf copy local : always gesetzt.

In diesem Projekt, in dem ich mein Paket installiere, muss importantfile.xmlcopy local : always sein.

Wie kann ich das erreichen?

Anmerkungen:

Ich kann setze copy local : always auf die Datei kurz nach der Installation des Pakets, das ist keine große Sache. Ich würde damit leben, wenn spätere Aktualisierungen des Pakets diese Eigenschaft unverändert lassen würden, was nicht der Fall ist. Beim Aktualisieren des Pakets wird copy local auf never zurückgesetzt (wie angegeben hier ).

Es gibt eine Nuspec-Datei im Projektordner, hier ist es:

<?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>
56
Johnny5

Sie können PowerShell und den von NuGet bereitgestellten Install.ps1-Hook verwenden.

Siehe die Dokumentation .

Über PowerShell müssen Sie nach dem Inhaltselement suchen, das Ihren importantfile.xml in einem Attribut enthält. Wenn das Skript es gefunden hat, muss es <CopyToOutputDirectory>Always</CopyToOutputDirectory> als untergeordnetes Element hinzugefügt werden.

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

Sie finden einige PowerShell-Snippets hier . Schauen Sie sich einfach die .ps1-Dateien an.

Sie könnten Folgendes versuchen (nicht getestet). Die Datei muss Install.ps1 heißen und in den tools-Ordner kopiert werden:

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

Sie sollten auch überprüfen, ob alles vollständig entfernt wurde, wenn Sie das Paket deinstallieren.

Anmerkung von Jonhhy5

Beim Aktualisieren des Pakets über update-package warnt Visual Studio, dass das Projekt "außerhalb der Umgebung" geändert wird. Das wird durch $doc.Save($project.FullName) verursacht. Wenn ich auf vor laden klicke, wird der Befehl vollständig abgebrochen, was manchmal zu Fehlern führt. Der Trick besteht darin, den Dialog dort zu belassen, bis der Prozess abgeschlossen ist, und dann die Projekte neu zu laden.

3
timmkrause

Anstatt ein PowerShell-Skript zu verwenden, besteht ein anderer Ansatz darin, eine MSBuild-Ziele oder eine Requis-Datei mit demselben Namen wie die Paket-ID zu verwenden:

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

Fügen Sie dann in der Datei nuspec die erforderlichen Dateien nicht dem Verzeichnis Content hinzu, sondern fügen Sie sie zusammen mit der Zieldatei dem Verzeichnis Build hinzu.

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

Wenn Sie unterschiedliche Inhalte für unterschiedliche Architekturen benötigen, können Sie unter Build auch Architekturordner mit jeweils einer eigenen Zieldatei hinzufügen.

Vorteile der Verwendung einer Zieldatei über das PowerShell-Skript mit dem NuGet-Verzeichnis Content:

  • erforderliche Inhaltsdateien werden im Projekt in Visual Studio nicht angezeigt
  • inhaltsdateien werden verknüpft und nicht in das Verzeichnis jedes Projekts kopiert, das auf das NuGet-Paket verweist (verhindert, dass mehrere Kopien vorhanden sind und dasselbe Verhalten wie für Baugruppen/Bibliotheken aus NuGet-Paketen beibehalten wird) 
  • PowerShell-Skripts funktionieren nur in Visual Studio und werden nicht ausgeführt, wenn NuGet von der Befehlszeile aus ausgeführt wird (Build-Server, andere IDEs und andere Betriebssysteme). Dieser Ansatz funktioniert überall
  • PowerShell-Installationsskripte werden nicht in NuGet 3.x project.json-System unterstützt.
127
kjbartel

Ich weiß, ihr habt eine funktionierende Lösung dafür, aber es hat für mich nicht funktioniert, also werde ich mitteilen, was ich aus dem NLog.config-Paket NuGet install.ps1 (github source here ).

HINWEIS: Dies ist nicht mein Code, sondern der Inhalt der install.ps1 von Das NLog.config-Nuget-Paket teilt nur das Wissen.

Es scheint mir etwas geradliniger zu sein und zu hoffen, anderen zu helfen, die wahrscheinlich darüber stolpern werden.

Die akzeptierten int-Werte für BuildAction finden Sie hier und die akzeptierten Werte für CopyToOutputDirectory hier .

wenn der Link erneut bricht enter image description here

Felder PrjBuildActionCompile 1
.__ Die Datei wird kompiliert.

prjBuildActionContent 2
Die Datei ist in der Content-Projektausgabegruppe enthalten (siehe Bereitstellen von Anwendungen, Services und Komponenten).

prjBuildActionEmbeddedResource 3
Die Datei ist in der generierten Assembly oder in einer Satellitenassembly als Ressource enthalten.

prjBuildActionNone 0
Es wird nichts unternommen.

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
37
workabyte

Ich habe dies gemacht, das Dateien aus meinem Build-Ordner in den Ausgabeordner kopiert (bin/debug oder bin/release). Funktioniert für mich wie ein Zauber.

Nuspec-Datei:

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

MeineProjekt.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>
5
Rahbek

Ich habe ein kleines Tool namens NuGetLib geschrieben, um nach dem Build automatisch Dateien zum Nuget-Paket hinzuzufügen.

  1. erstellen Sie einen tools-Ordner mit Ihrem Install.ps1-Skript
  2. baue deine nugetPackage
  3. fügen Sie den Tools-Ordner der erstellten nugetPackage hinzu.

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

0
Dominic Jonas