Including content files in .csproj that are outside the project cone

csproj content include wildcard
csproj compile include link
csproj file
dotnet add file to project
msbuild project types
msbuild include directory
msbuild project file
visual studio 2017 add as link

I have a C# project say MyProject.csproj located at "C:\Projects\MyProject\". I also have files that I want copied into the output directory of this project. But, the files are at the location "C:\MyContentFiles\", i.e. they are NOT within the project cone. This directory has sub-directories as well. The contents of the directory is not managed. Hence I have to include all what is under it.

When I include them as 'Content' in the project, they are copied, but the directory structure is lost. I did something like this:-

<Content Include="..\..\MyContentFiles\**">
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

How do I copy these files/directories recursively into the output directory of the project with the directory structure preserved?

You need to add file as a link:

  1. Right click on the project in VS.
  2. Add -> Existing Item...
  3. Find the file.
  4. Select it and.
  5. Add as a Link (drop down in the Add Button in the dialog).
  6. Open the properties of the file and set "Copy to Output Directory" to "Copy always".

BUT You cannot do it for the directory tree. Instead you need to write post-build task for that. This is a sample that will get you stared.

Including linked files from outside the project directory in ASP. You can always directly edit the .csproj file yourself and add the necessary items by hand. For content files like JSON configuration files, you would use the  CPS made a change to not show the files outside the project cone to avoid showing some packages that were including files from the nuget packages directory. However if projects include file either using globs or directly then they don't show up in soln explorer.

I believe @Dmytrii gets it right on one hand - you want to use the "link" feature.

However, he's only partly correct when saying you can't link to a directory tree. While this is, indeed, true when trying to add the links using Visual Studio's GUI, MSBuild supports this.

If you want to preserve the directory structure, just add the %(RecursiveDir) tag to your <link> node:

<Content Include="..\..\MyContentFiles\**\*.*">
  <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

The page MSBuild Well-known Item Metadata goes into more detail on the metadata you can access.

You need to add the file as a link: Right click on the project in VS. Add → Existing Item Find file. Select it and. Add as a link (dropdown in the Add button in the  Including content files in .csproj that are outside the project cone. You need to add file as a link: Right click on the project in VS. Add -> Existing Item Find the file. Select it and. Add as a Link (drop down in the Add Button in the dialog). Open the properties of the file and set "Copy to Output Directory" to "Copy always".

The answer of Mandark adds the content files directly to the solution, and they will show up in the solution explorer. Whenever a file is added or deleted in the original directory, this is not picked up by visual studio automatically. Also, whenever a file is deleted or added in the solution explorer, the project file is altered, and all files are included separately, instead of just including the folder.

To prevent this, you can use the same trick, but put it in a separate project file and then import it.

The project file (for example include.proj) looks like this:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Content Include="..\..\MyContentFiles\**">
  <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

In your own project file, add the following line

<Import Project="include.proj" />

Visual Studio will not mess with this file, and just adds files as content during a build. Changes in the original directory are always included. The files won't show up in your solution explorer, but will be included in the output directory.

Picked up on this trick here: http://blogs.msdn.com/b/shawnhar/archive/2007/06/06/wildcard-content-using-msbuild.aspx

msbuild Including content files in .csproj that are outside the project cone? <​Content Include="..\..\MyContentFiles\**\*.*"> \*.*. 1) What happens if a file is deleted  Adding files from outside the project by linking. To add a file as a link, right click and choose Add > Existing Item… as before, but this time, don't click the Add button. Instead, click the little dropdown arrow next to the Add button and select Add as Link.

The following, which you would add to the bottom of your project file, will copy your content files maintaining the directory structure in a after build event to the target directory $(TargetDirectory) of your build (typically $(MSBuildProjectDirectory)\bin\Debug ).

<ItemGroup>
    <ExtraContent Include="$(MSBuildProjectDirectory)\..\..\MyContentFiles\**" />
</ItemGroup>

<Target Name="AfterBuild">
    <Copy 
        SourceFiles="@(ExtraContent)" 
        DestinationFiles="@(ExtraContent->'$(TargetDir)\%(RecursiveDir)%(Filename)%(Extension)')" 
        SkipUnchangedFiles="true" />
</Target>

If these files needed to go in a directory named MyContentFiles, you could add this before the copy:

<MakeDir Directories="$(TargetDir)\MyContentFiles" Condition=" !Exists('$(TargetDir\MyContentFiles') " />

and change

<Copy 
            SourceFiles="@(ExtraContent)" 
            DestinationFiles="@(ExtraContent->'$(TargetDir)\%(RecursiveDir)%(Filename)%(Extension)')" 
            SkipUnchangedFiles="true" />

To

<Copy 
            SourceFiles="@(ExtraContent)" 
            DestinationFiles="@(ExtraContent->'$(TargetDir)\MyContentFiles\%(RecursiveDir)%(Filename)%(Extension)')" 
            SkipUnchangedFiles="true" />

CPS made a change to not show the files outside the project cone to However if projects include file either using globs or directly then they don't something outside my project, I don't need to see it -- but if my csproj has it, I want to see it. Content Visible=false hides the item, but not the directories in  Including content files in.csproj that are outside the project cone ; VS2010 How to include files in project, to copy them to build output directory automatically during build or publish ; Returning binary file from controller in ASP.NET Web API

I think

<Content Include="..\..\MyContentFiles\**\*.*">
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

Is just enough, since you want everything in that folder and subfolders

NET core project and have a file linked to the project which has This issue does not repro if xyz.txt is just a regular file in the project tree with build action None. Even clicking save all doesn't change the contents of csproj on the disk, for a linked file which lies outside the project cone causes the item to  I am trying to include stylecop.json in my C# project on Visual Studio 2017. I have figured out how to do this by modifying the .csproj in any text editor: <;AdditionalFiles Include="stylecop.js

Including content files in .csproj that are outside the project cone. I have a C# project say MyProject.csproj located at "C:\Projects\MyProject\". I also have files  dotnet build or dotnet publish. DLLs are generated and dropped within ProjectD/src/dlls/* due to xcopy post build steps included in project A and project B. DLLs are NOT copied to output directory or publish directory of project D. dotnet build or dotnet publish command run a second time.

Including content files in .csproj that are outside the project cone. I have a C# project say MyProject.csproj located at "C:\Projects\MyProject\". I also have files  Additions to the csproj format for .NET Core. 04/08/2019; 16 minutes to read +29; In this article. This document outlines the changes that were added to the project files as part of the move from project.json to csproj and MSBuild. For more information about general project file syntax and reference, see the MSBuild project file documentation.

In MSBuild, an item is a named reference to one or more files. If set to false , does not include the output of the referenced project as a Reference of this when the file is physically located outside the influence of the project file. Content. Represents files that are not compiled into the project, but may be  In this way, the project file is instructing MSBuild to construct lists of files that need to be processed in the same way—the Reference list includes assemblies that must be in place for a successful build, the Compile list includes code files that must be compiled, and the Content list includes resources that must be copied unaltered. We'll

Comments
  • As stated in this answer, the "You cannot do it for the directory tree." statement isn't true.
  • 1) What happens if a file is deleted from the Shared Assets store? It doesn't look like it will be deleted from the Solution Dir 2) Is there any way to get Visual Studio to delete these files from $(SolutionDir) after run completes. Leaving them there might confuse other devs.
  • @Adam See my answer below
  • Being crashed in the wilderness with little food, water and having the strong need for companionship, I find this answer helpful. By following these instructions, I was able to build a fully functional AI that now has replaced all human needs that once haunted me in the wilderness here. Thanks Mandark!
  • @Vijay see my edit, you need <Content Include="..\..\MyContentFiles\**\*.*"> - note the \*.* at the end of the path.
  • Not working for a .NET Core project on VS2017 (15.8.6).
  • For some reason, this didn't seem to work for me using a .proj file, but I was able to make it work with a .csproj file.
  • You can add <Visible>true</Visible> to the Content element to make the items appear in Solution Explorer.
  • Mine was ok with just a .proj
  • This didn't work for me at all and I'm assuming it's because the items-to-be-linked themselves were generated in a pre-build event.
  • Not working for a .NET Core project on VS2017 (15.8.6).
  • Your transforms have a type-o: @(ExtraContent)->'...') should be @(ExtraContext->'...'). Otherwise good answer!
  • @Todd 1) What happens if a file is deleted from the MyContentFiles store? It doesn't look like it will be deleted from the Solution Dir 2) Is there any way to get Visual Studio to delete these files from $(SolutionDir) after run completes. Leaving them there might confuse other devs.