web-dev-qa-db-ja.com

nugetパッケージでコンテンツファイルを「copy local:always」に設定します

ビルド後のイベントでこのコマンドを使用して、プロジェクトからヌゲットパッケージを生成します。変数%conf%は正しい構成(デバッグまたはリリース)に設定され、%1はプロジェクト名(例:「MyCompany.MyProject」)です。

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

このパッケージは私たち自身の使用のみを目的としており、nugetで公開されることはありません。それは私たちのプライベートリポジトリで終わります。

プロジェクトには、generate action : contentおよびcopy local : alwaysに設定されたファイルがあります。 (私の視覚的なスタジオはフランスにあるので、私はその伝達について100%確信がありません)。 importantfile.xmlという名前を付けましょう。

生成されたパッケージでは、この構造になります:

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

これは問題ありません。importantfile.xmlをパッケージにデプロイしたいのです。というのも、このファイルは重要だからです!

パッケージを別のプロジェクトにインストールすると、importantfile.xmlがプロジェクトのルートにデプロイされます。それで大丈夫です。ただし、copy local : alwaysには設定されていません。

パッケージをインストールするこのプロジェクトでimportantfile.xmlになるにはcopy local : alwaysが必要です。

どうすればそれを達成できますか?

注:

Icanパッケージをインストールした直後にcopy local : alwaysをファイルに設定しますが、大したことではありません。後でパッケージを更新してこのプロパティをそのままにして、そうでない場合は、私はそれで生きます。パッケージを更新すると、copy localneverにリセットされます(前述のとおり here )。

プロジェクトのフォルダーにnuspecファイルがあります。ここにあります:

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

PowerShellとNuGetが提供する_Install.ps1_フックを使用できます。

ドキュメント を参照してください。

PowerShellを介して、属性に_importantfile.xml_を含むコンテンツ要素を「検索」する必要があります。スクリプトがそれを見つけたら、_<CopyToOutputDirectory>Always</CopyToOutputDirectory>_を子要素として追加する必要があります。

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

いくつかのPowerShellスニペットを見つけることができます こちら 。 _.ps1_ファイルをご覧ください。

以下を試すことができます(テストされていません)。ファイルには_Install.ps1_という名前を付け、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)
    }
}
_

パッケージをアンインストールするときに、すべてが完全に削除されたかどうかも確認する必要があります。

Jonhhy5による注

_update-package_を介してパッケージを更新すると、Visual Studioはプロジェクトが「環境外」で変更されたことを警告します。 $doc.Save($project.FullName)が原因です。 reloadbeforeをクリックすると、コマンドが完全に終了し、エラーが発生することがあります。秘Theは、プロセスが完了するまでダイアログをそこに残し、thenプロジェクトをリロードすることです。

2
timmkrause

PowerShellスクリプトを使用する代わりに、パッケージIDと同じ名前で MSBuildターゲットまたはpropsファイル を使用する別の方法があります。

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

Nuspecファイルで、必要なファイルをContentディレクトリに追加する代わりに、ターゲットファイルとともにBuildディレクトリに追加します。

  • ビルド
    • importantfile.xml
    • MyPackage.targets
  • lib
    • net45
      • MyAssembly.dll

アーキテクチャごとに異なるコンテンツが必要な場合は、Buildの下にそれぞれ独自のターゲットファイルを持つアーキテクチャフォルダを追加できます。

NuGet ContentディレクトリでPowerShellスクリプトよりもターゲットファイルを使用する利点:

  • 必要なコンテンツファイルがVisual Studioのプロジェクトに表示されない
  • コンテンツファイルは、NuGetパッケージを参照する各プロジェクトのディレクトリにコピーされるのではなくリンクされます(複数のコピーが存在することを防ぎ、NuGetパッケージのアセンブリ/ライブラリと同じ動作を維持します)
  • PowerShellスクリプトはVisual Studioでのみ機能し、 NuGetがコマンドラインから実行されている場合は実行されません (ビルドサーバー、他のIDE、および他のOS)、このアプローチはどこでも機能します
  • PowerShellインストールスクリプトは NuGet 3.x project.jsonシステムではサポートされていません です。
137
kjbartel

私はあなたたちがこれに有効な解決策を手に入れたことを知っていますが、私にとってはうまくいきませんでしたので、私は NLog.config NuGetパッケージ install.ps1(github source- ここ )。

注:これは私のコードではなく、知識を共有しているNLog.config nugetパッケージのinstall.ps1のコンテンツです。

私にはもう少し率直で、これにつまずく可能性のある他の人たちを助けたいと思っています。

BuildAction here の受け入れられたint値と、CopyToOutputDirectory here の受け入れられた値を見つけることができます。

リンクが再び壊れた場合 enter image description here

フィールドprjBuildActionCompile 1
ファイルがコンパイルされます。

prjBuildActionContent 2
このファイルはコンテンツプロジェクトの出力グループに含まれています(アプリケーション、サービス、およびコンポーネントの展開を参照)

prjBuildActionEmbeddedResource 3
ファイルは、リソースとしてメイン生成アセンブリまたはサテライトアセンブリに含まれています。

prjBuildActionNone 0
アクションは実行されません。

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

ビルドフォルダーから出力フォルダー(bin/debugまたはbin/release)にファイルをコピーするこれを作成しました。私にとって魅力的な作品です。

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

ビルド後に自動的にファイルをnugetパッケージに追加するNuGetLibという小さなツールを作成しました。

  1. Install.ps1スクリプトでtoolsフォルダーを作成します
  2. nugetPackageを構築します
  3. toolsフォルダーをビルドされたnugetPackageに追加します

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

0
Dominic Jonas