Copy files to output directory using csproj dotnetcore
Solution 1
There's quite a few ways to achieve your goals, depending on what your needs are.
The easiest approach is setting the metadata (CopyToOutputDirectory
/ CopyToPublishDirectory
) items conditionally (assuming .txt
being a None
item instead of Content
, if it doesn't work, try <Content>
instead):
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
<None Update="foo.txt" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
If more control is required, the most versatile approach is to add custom targets that hook into the build process in the csproj file:
<Target Name="CopyCustomContent" AfterTargets="AfterBuild">
<Copy SourceFiles="foo.txt" DestinationFolder="$(OutDir)" />
</Target>
<Target Name="CopyCustomContentOnPublish" AfterTargets="Publish">
<Copy SourceFiles="foo.txt" DestinationFolder="$(PublishDir)" />
</Target>
This copies a file to the respective directories. For more options for the <Copy>
task, see its documentation. To limit this to certain configurations, you can use a Condition
attribute:
<Target … Condition=" '$(Configuration)' == 'Release' ">
This Condition
attribute can be applied both on the <Target>
element or on task elements like <Copy>
.
Solution 2
While this helped me get my issue sorted, it didn't work for all files in a sub-directory. I also used Content Include
rather than Content Update
.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Content Include="layouts\*.*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
Solution 3
Assuming you have an assets
folder in your root directory. You can name it as you want. This is just an example:
your-project.csproj
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<AssetsSourceFiles Include="assets/**/*.*"/>
</ItemGroup>
<Target Name="CopyCustomContent" AfterTargets="AfterBuild">
<Copy SourceFiles="@(AssetsSourceFiles)" DestinationFolder="$(OutDir)" SkipUnchangedFiles="true" />
</Target>
</Project>
this copies only the content of the assets
folder to the output root without wrapping it into the assets
folder. But if you want to copy with the folder itself, you can use the following code:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<Content Include="assets\**\*.*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
Solution 4
Place this in your .csproj file, replacing nlog.config with the desired file path. Then simply save it and build your project:
<ItemGroup>
<Content Update="Nlog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
Solution 5
I had the requirement for a selection of HTML templates to be consumable both client-side and server-side (Handlebars js)
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Content Update="wwwroot\html-templates\**\*.*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
Related videos on Youtube

Comments
-
BillHaggerty about 2 years
So my issue is pretty simple. I have some files that I want to be copied to the build output directory whether it is a debug build or a release publish. All of the information I can find is about the old json config approach. Anyone have an example using the csproj with dotnetcore?
-
user7817808 about 5 yearsEvery other permutation of all of the other answers/suggestions failed to work for me. Not even a mention of the file in verbose build output. But your suggestion here worked.
-
JSancho almost 5 yearsAnd if you want to include intermediate subfolders use
<Content Include="layouts\**\*.*">
-
notracs about 4 yearsWhen using the Web SDK (
<Project Sdk="Microsoft.NET.Sdk.Web">
) it wont allow you to useInclude=
because it is already seems to implicitly specify that within the SDK. I had to useUpdate=
to get it to build and include my additional files. -
null about 4 yearsThis doesn't appear to copy subdirectories.
-
Bruno Garcia almost 4 yearsIdeally use a <Copy> task to make it cross platform.
-
Dominik over 3 yearsNice, thanks.. But how to copy only the content of the folder to the output directory not the folder itself. The expression
assets\*.*
should assume it. But it copies the complete assets folder. So I havebin/Debug/netcoreapp3.1/assets/...
But I want the files of the assets folder to the root directory of the output.bin/Debug/netcoreapp3.1/...
. -
Dominik over 3 yearsI found a solution:
xml <Project Sdk="Microsoft.NET.Sdk"> <ItemGroup> <AssetsSourceFiles Include="assets/**/*.*"/> </ItemGroup> <Target Name="CopyCustomContent" AfterTargets="AfterBuild"> <Copy SourceFiles="@(AssetsSourceFiles)" DestinationFolder="$(OutDir)" SkipUnchangedFiles="true" /> </Target> </Project>
(see my answer for a better code format.) -
Reahreic over 3 yearsHow would i apply 'DestinationFolder' to <Reference> items, or is it event possible, there's not much in the docs that i can find. I don't want all my assemblies at the root level and would prefer them to be in their own folder.
-
Martin Ullrich over 3 yearsYou can set
DestinationSubDirectory="subdir\"
metadata onReference
items directly. However this means you need to implement assembly resolution yourself (AssemblyResolve event) -
kuldeep over 3 yearsHow can I copy parent folder that contains some dlls in respective folders. I want to make them available in the output published path so that after build these folders r available for my application at run time, as I load these dlls as plugins at startup. I am using rider on mac
-
Vedran Mandić almost 3 yearsExcellent, I was missing the assets**. ... the two wildcards to specify depth. Thanks!
-
nedstark179 over 2 yearsNot sure why, but I had to use
<None Update="layouts\*.*>
to get mine to work -
Nathan Goings almost 2 yearsWarning, if you are using Azure Pipelines and the files to be copied do not exist except from a PreBuild step in the same
.csproj
file. You will run into a chicken-and-egg problem where the build agent "misses" the files. It may be related to the warning they provide during the build step: docs.microsoft.com/en-us/azure/devops/pipelines/tasks/build/…