Last time I had to find out how to extract some files from a Nuget package in took me at least 6 months but I finally managed to find the solution.
The thing is that, this solution assumes I have a .nupkg
file and manually add a .targets
file to perform the extraction process.
Now, things are different:
.nupgk
file, we generate one automatically on our VSTS server using the dotnet pack
command. Then we consume the package from our Nuget serverHere is my 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>
As you can see I tried several different settings. This MsBuild results in a NLog.config
file included in a NLog
folder at the root of the Nuget package file.
During my different tries, depending of the configuration I set, I was able to end-up with the NLog.config
file at src/ProjectName.Logging/NLog/NLog.config
or even at lib/netstandard2.0/Nlog.config
.
So my file is definitely included in my Nuget package file but isn't copied in the output directory of the project that consumes the package.
I tried to specify a .nuspec
file when generating my package with dotnet pack
like described here but I was never able to get a desired result (either only my NLog.config
was included in the Nuget package or all the source files). Moreover, this has several downsides like overriding the configuration in the .csproj
file or adding useless complexity. I believe what I want to achieve could be done without using a .nuspec
file (maybe I'm wrong).
I noticed the build/ProjectName.targets
file is missing in my package and this is probably the missing piece. So how to add this .targets
file without manually modifying the package?
Is there another way to copy my config file out of the Nuget package to the output directory?
I really hope someone could help me solve this issue. This is the 2nd time I want to perform the same operation but with a slight difference and once again this is hard to do.
Thanks a lot
It is possible to copy files without the .nuspec
file, if you create your nuget from the .csproj
file as described here.
And to copy files from nuget to output directory, create a ProjectName.targets
file with the following content:
<ItemGroup>
<LogFiles Include="$(MSBuildThisFileDirectory)\..\contentFiles\LogFiles\*.config" />
</ItemGroup>
<Target Name="CopyLogFiles" BeforeTargets="Build">
<Copy SourceFiles="@(LogFiles)" DestinationFolder="$(TargetDir)CopiedLogFiles\" />
</Target>
In your .csproj
file add:
<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>
The paths and names can of course be freely chosen.
This should copy all .config
files to a folder called CopiedLogFiles
in the output directory!