My text file is in my class library project. I have its Build Action set to Content and Copy to Output Directory set to Copy if newer, so the .csproj has a section like:
<ItemGroup>
<Content Include="MyFile.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
I'm doing this because I need to use the text file from my class library, and can't have it as an embedded resource because I want to allow end-users to edit it. When I use VS 2017 to create the package it gives me a .nuspec with a section like this:
<contentFiles>
<files include="any/net46/MyFile.txt" buildAction="Content" />
<files include="any/netstandard1.3/MyFile.txt" buildAction="Content" />
</contentFiles>
Then when I reference the package from another project, MyFile.txt appears at the root of the project with Build Action set to Content but Copy to Output Directory set to Do not copy. I just want the file to be included alongside the .dll, without being included in the referencing project.
The following will create a nuget package that persists your chosen file(s) alongside your package's dll when a consuming application installs it and can be done entirely through the Visual Studio 2017 IDE.
Let's pretend you have a C# project called Foo.Bar in your solution that you would like to build into a nuget package:
In Visual Studio, right-click the project Foo.Bar > Properties
and go to the Package
tab. Make sure the value for Package id:
is Foo.Bar
.
Create a Foo.Bar.targets
file in the same directory as your Foo.Bar.csproj
file with the following content:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)\MyFile.txt">
<Link>MyFile.txt</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
Right click the project in Visual Studio 2017, and select Edit Foo.Bar.csproj
. Put the following block in the opened project file:
<ItemGroup>
<None Include="MyFile.txt">
<Pack>true</Pack>
<PackagePath>build</PackagePath>
</None>
<None Include="Foo.Bar.targets">
<Pack>true</Pack>
<PackagePath>build</PackagePath>
</None>
</ItemGroup>
Now when you right click the project and select Pack
(or if you run dotnet pack
from the command line in the directory where your project resides), it will generate a .nupkg
file for your Foo.Bar
project. MyFile.txt
and Foo.Bar.targets
will be in the build
folder inside of it.
As a test I installed it into a sample Console App project. After doing so, MyFile.txt
is present in the Solution Explorer of the Console App and can be opened and edited. Furthermore, if I publish the console app, both Foo.Bar.dll
and MyFile.txt
are in the bin > Release > [TargetFramework] > publish
folder of the published files (if published using a Folder Profile to local disk).
An interesting thing to note is that at time of writing, if you right click MyFile.txt
in the Console App that installed the package and select Properties
, you'll see that Copy to Output Directory
is set to Always
. If I try to change it to Do Not Copy
or anything else, it will revert back to Always
when the dialog is closed despite clicking OK
. It will act as if you click Cancel
every time. This is because of the edit made to the original Foo.Bar.csproj
file that produced the nuget package, specifically: <CopyToOutputDirectory>Always</CopyToOutputDirectory>
.
If you want to keep .nuspec, then you can edit it manually and add copyToOutput="true"
attribute.
If you're using VS2017 and want to edit your .csproj, then you should be able to specify extra metadata in your .csproj file (and you can set custom build action if necessary):
<Content Include="MyFile.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<IncludeInPackage>true</IncludeInPackage>
<BuildAction>Content</BuildAction>
<CopyToOutput>true</CopyToOutput>
</Content>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With