Automatic copy files to output during application building

There is Copy to Output Directory property for files in C# projects. But in VC++ projects it is absent. I know, that I can use Build events in VC++ and write there something like

xcopy /y /d %(FullPath) $(OutDir)

Is there a way to avoid the use of CMD (and other scripting methods)? Can msbuild do something to help in this case?


Solution 1:

Can MSBuild do something to help in this case?

Using MSVC 2012, this worked for me:

Assumed you have a file "Data/ThisIsData.txt" in your c++ Project.

Unload the project (right click --> Unload Project).
Edit project XML (right click --> Edit .vcxproj)
Now you see the projects MSBuild file as XML in your editor.

Find "ThisIsData.txt". It should look something like:

<ItemGroup>
<None Include="Data\ThisIsData.txt" />
...
</ItemGroup>

Now add an other item group like this:

<ItemGroup>
<Content Include="Data\ThisIsData.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
...
</ItemGroup>

Reload the project and build.
Your file "ThisIsData.txt" should get copied to $(OutDir)\Data\ThisIsData.txt.

Why duplicating the ItemGroup?

Well if you simply change the None include to a content include, the IDE does not seem to like it any more, and will not display it. So to keep a quick edit option for my data files, I decided to keep the duplicated entries.

Solution 2:

In VS 2015 it is possible to give C projects the functionality that is in C#. (Idea from building off of jochen's answer.) Instead of adding another ItemGroup, modify the given itemgroup adding a CopyTo element. I.E, using his example, simply enhance the original entry to:

<ItemGroup>
  <None Include="Data\ThisIsData.txt" />
    <DeploymentContent>true</DeploymentContent>
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
...
</ItemGroup>

No other ItemGroup required. By adding the CopyTo element, you add an "Included In Project" property.

VS 2015 C Property with Included In Project added

Solution 3:

In Visual Studio 2017 you can do this in the IDE. I am not sure about earlier versions.

Simply add the file as an included project file so it shows in the Solution Explorer. Then right click on the file and select the Properties menu.

Change the Content to "Yes" and change the Item Type to "Copy file"

If you look at the changes it made to the project file you can see it added this:

<ItemGroup>
  <CopyFileToFolders Include="Filename.txt">
    <DeploymentContent>true</DeploymentContent>
    <FileType>Document</FileType>
  </CopyFileToFolders>
</ItemGroup>