web-dev-qa-db-ja.com

.csprojのMsBuildとdotnet packコマンドを使用してNugetパッケージから出力ディレクトリにファイルをコピーする

前回、Nugetパッケージからいくつかのファイルを抽出する方法を見つける必要がありましたが、少なくとも6か月かかりましたが、ようやく ソリューション を見つけることができました。

つまり、このソリューションでは、.nupkgファイルがあり、手動で.targetsファイルを追加して抽出プロセスを実行することを前提としています。

今、状況は異なります。

  1. .nupgkファイルがありません。dotnet packコマンドを使用して、VSTSサーバーで自動的に生成します。次に、Nugetサーバーからパッケージを使用します
  2. 解決策を見つけるまでにさらに6か月かかる余裕はありません

こちらが私のProjectName.csprojです

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <TargetFramework>netstandard2.0</TargetFramework>
        <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
        <Authors>Jérôme MEVEL</Authors>
        <Version>1.0.3</Version>
        <GeneratePackageOnBuild>true</GeneratePackageOnBuild>

        <!-- This answer got many votes on a Github thread so I tried just in case -->
        <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>

        <!-- Just trying that too-->
        <IncludeBuildOutput>true</IncludeBuildOutput>
        <IncludeContentInPack>true</IncludeContentInPack>

        <!-- I wanted to see the full generated Nuget package -->
        <IncludeSource>true</IncludeSource>

        <!-- desperate attempt -->     
        <TargetsForTfmSpecificBuildOutput>GetMyPackageFiles</TargetsForTfmSpecificBuildOutput>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Dapper" Version="1.50.5" />
        <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.1" />
        <PackageReference Include="Microsoft.Extensions.Logging" Version="2.1.1" />
        <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.1.1" />
        <PackageReference Include="NLog" Version="4.5.8">

            <!-- Let's try this too just in case-->
            <IncludeAssets>all</IncludeAssets>
        </PackageReference>
        <PackageReference Include="NLog.Extensions.Logging" Version="1.2.1">
            <IncludeAssets>all</IncludeAssets>
        </PackageReference>
        <PackageReference Include="NLog.Web.AspNetCore" Version="4.6.0">
            <IncludeAssets>all</IncludeAssets>
        </PackageReference>
        <PackageReference Include="System.Data.Common" Version="4.3.0" />
        <PackageReference Include="System.Data.SqlClient" Version="4.5.1" />
    </ItemGroup>
    <ItemGroup>

        <!-- Added the file to the root folder in case <IncludeAssets>all</IncludeAssets> is looking there -->
        <Content Include="NLog.config">
            <Pack>true</Pack>
            <PackagePath>NLog;;</PackagePath>
            <CopyToOutputDirectory>Always</CopyToOutputDirectory>
        </Content>

        <!-- My desired path to look for the file -->
        <Content Include="NLog\NLog.config">
          <Pack>true</Pack>
          <PackagePath>NLog;;</PackagePath>
          <CopyToOutputDirectory>Always</CopyToOutputDirectory>
        </Content>
    </ItemGroup>

    <!-- This is the default setting, perfectly working when I reference the project instead of installing the Nuget package -->
    <ItemGroup>
        <None Update="NLog\NLog.config">
            <CopyToOutputDirectory>Always</CopyToOutputDirectory>
        </None>
    </ItemGroup>

    <!-- desperate attempt -->
    <Target Name="GetMyPackageFiles">
        <ItemGroup>
            <BuildOutputInPackage Include="NLog/Nlog.config">
                <TargetPath>NLog</TargetPath>
            </BuildOutputInPackage>
        </ItemGroup>
    </Target>
</Project>

ご覧のとおり、いくつかの設定を試しました。このMsBuildの結果、NLog.configファイルがNugetパッケージファイルのルートのNLogフォルダーに含まれます。

enter image description here

何度か試してみたところ、設定に応じて、NLog.configにあるsrc/ProjectName.Logging/NLog/NLog.configファイル、またはlib/netstandard2.0/Nlog.configにさえ到達することができました。

したがって、私のファイルは間違いなくNugetパッケージファイルに含まれていますが、パッケージを使用するプロジェクトの出力ディレクトリにはコピーされません。

ここで説明 のように.nuspecを使用してパッケージを生成するときにdotnet packファイルを指定しようとしましたが、希望する結果を得ることができませんでした(私のNLog.configのみ) Nugetパッケージまたはすべてのソースファイルに含まれていました)。さらに、これには、.csprojファイルの設定を上書きしたり、役に立たない複雑さを追加したりするなど、いくつかの欠点があります。私が達成したいことは、.nuspecファイルを使用せずに実行できると信じています(おそらく私は間違っています)。

build/ProjectName.targetsファイルがパッケージにないことに気付きましたが、これはおそらく欠けている部分です。では、手動でパッケージを変更せずに、この.targetsファイルを追加する方法は?

Nugetパッケージから出力ディレクトリに構成ファイルをコピーする別の方法はありますか?

私は誰かがこの問題を解決するのを助けてくれることを本当に望んでいます。同じ操作を実行したいのは2回目ですが、わずかな違いがありますが、これも難しいです。

どうもありがとう

5
Jérôme MEVEL

説明されているように.nuspecファイルからnugetを作成する場合、.csprojファイルなしでファイルをコピーすることは可能です here

また、nugetから出力ディレクトリにファイルをコピーするには、次の内容のProjectName.targetsファイルを作成します。

<ItemGroup>
    <LogFiles Include="$(MSBuildThisFileDirectory)\..\contentFiles\LogFiles\*.config" />
</ItemGroup>
<Target Name="CopyLogFiles" BeforeTargets="Build">
    <Copy SourceFiles="@(LogFiles)" DestinationFolder="$(TargetDir)CopiedLogFiles\" />
</Target>

.csprojファイルに以下を追加します。

<ItemGroup Label="FilesToCopy">
   <Content Include="ProjectName.targets" PackagePath="build/ProjectName.targets" />
   <Content Include="LogFiles\*.config" Pack="true" PackagePath="contentFiles\LogFiles">
     <PackageCopyToOutput>true</PackageCopyToOutput>
   </Content>
</ItemGroup>

パスと名前はもちろん自由に選択できます。

これにより、すべての.configファイルが出力ディレクトリのCopiedLogFilesというフォルダーにコピーされます。

5
wmorian

はい、ようやくソリューションが見つかりました。これには.nuspecファイルと.targetsファイルも含まれています。

ProjectName.csprojはこれを含める必要があります

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <TargetFramework>netstandard2.0</TargetFramework>
        <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
        <NuspecFile>ProjectName.Logging.nuspec</NuspecFile>  
    </PropertyGroup>

    <!-- This is just for some projects referencing this project directly instead of the Nuget package -->
    <ItemGroup>
        <Content Include="NLog\NLog.config">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </Content>
    </ItemGroup>

    <ItemGroup>
        <PackageReference Include="Dapper" Version="1.50.5" />
        <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.1" />
        <PackageReference Include="Microsoft.Extensions.Logging" Version="2.1.1" />
        <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.1.1" />
        <PackageReference Include="NLog" Version="4.5.8" />
        <PackageReference Include="NLog.Extensions.Logging" Version="1.2.1" />
        <PackageReference Include="NLog.Web.AspNetCore" Version="4.6.0" />
        <PackageReference Include="System.Data.Common" Version="4.3.0" />
        <PackageReference Include="System.Data.SqlClient" Version="4.5.1" />
    </ItemGroup>
</Project>

ProjectName.nuspecには、Nugetパッケージに関連するすべてのものを入れます

<?xml version="1.0"?>
<package >
    <metadata>
        <id>ProjectName.Logging</id>
        <version>1.1.0</version>
        <authors>Jérôme MEVEL</authors>
        <description>Just a logging component</description>
        <releaseNotes>Extract the NLog.config file automatically</releaseNotes>
        <dependencies>
            <dependency id="Dapper" version="1.50.5" />
            <dependency id="Microsoft.Extensions.DependencyInjection" version="2.1.1" />
            <dependency id="Microsoft.Extensions.Logging" version="2.1.1" />
            <dependency id="Microsoft.Extensions.Logging.Abstractions" version="2.1.1" />
            <dependency id="NLog" version="4.5.8" />
            <dependency id="NLog.Extensions.Logging" version="1.2.1" />
            <dependency id="NLog.Web.AspNetCore" version="4.6.0" />
            <dependency id="System.Data.Common" version="4.3.0" />
            <dependency id="System.Data.SqlClient" version="4.5.1" />
        </dependencies>
    </metadata>
    <files>
        <file src="bin\Release\netstandard2.0\ProjectName.Logging.dll" target="lib/netstandard2.0/ProjectName.Logging.dll" />    
        <file src="ProjectName.Logging.targets" target="build/ProjectName.Logging.targets" />
        <file src="NLog/Nlog.config" target="content/Nlog.config" />
    </files>
</package>

そして最後にProjectName.targets注意深い!ファイルはマシンのNugetキャッシュにあります。 Visual Studioではプロジェクトのルートに表示されますが、Windowsエクスプローラーでは表示できません(少なくともWindowsでは)。そのため、Visual Studioでファイルを変更すると、同じNugetパッケージ(および同じバージョン)を参照するこのマシン上の他のすべてのプロジェクトのファイルが変更されます。

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.Microsoft.com/developer/msbuild/2003">
    <ItemGroup>
        <Content Include="$(MSBuildThisFileDirectory)\..\content/NLog.config">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </Content>
    </ItemGroup>
</Project>

を使用してNugetパッケージを生成します dotnet pack nuget packコマンド(これ以上の経験があるので、dotnet pack.nuspecファイルではうまく機能しないことがわかっています。いくつかのバグがあります)結果は次のとおりです。

enter image description here

最後に、パッケージをインストールするだけで、ビルドプロセス中にNlog.configファイルがNugetキャッシュからプロジェクトの出力ディレクトリにコピーされます。

5
Jérôme MEVEL

。Net標準ライブラリ.csprojを使用する場合、nuget contentFiles CopyToOutputの値をどのようにtrueに設定しますか? がこの質問に対するより良い答えを提供すると思います。 https://github.com/NuGet/NuGet.Client/pull/145

.csprojでPackageCopyToOutputをtrueに設定して、nugetコンテンツファイルを「CopyToOutput = true」として宣言できます。このようにして、nugetを参照するプロジェクトは、参照するcsprojファイルで<CopyToOutput>true</CopyToOutput>でマークされたコンテンツファイルを持ち、コンテンツファイルを出力ディレクトリにコピーするようにmsbuildに指示します。

Nugetプロジェクトの.csprojで:

<Content Include="...">
    <PackageCopyToOutput>true</PackageCopyToOutput>
</Content>
1
luwei