For a (web-)project I am working on, I needed to copy the content of 1 website to a sub-folder of another website after the project was built. This enables the 2 projects being separately developed and deployed, but also allows the one project being deployed as a sub-site of the other one. Got it? 🙂

This is how I did this:
In the project file of the sub-project:

  1. In the project file I defined a few variables to make things easier
    <PropertyGroup>
    <MyOutputFolder>C:ProjectOutputFolder</MyOutputFolder>
    <OutputSubFolder>SubFolder</OutputSubFolder>
    </PropertyGroup>
  2. I defined what files to copy, with the binary output (dll) separately from the website content:
    <ItemGroup>
    <MyCopyItems Include="$(MSBuildProjectDirectory)***.aspx" />
    <MyCopyItems Include="$(MSBuildProjectDirectory)***.htm?" />
    <MyCopyItems Include="$(MSBuildProjectDirectory)***.js" />
    <MyCopyItems Include="$(MSBuildProjectDirectory)***.gif" />
    <MyCopyItems Include="$(MSBuildProjectDirectory)***.jp?g" />
    <MyCopyItems Include="$(MSBuildProjectDirectory)***.png" />
    <MyCopyBin Include="$(MSBuildProjectDirectory)bin***.dll" />
    </ItemGroup>
  3. I created a new target that performs 2 copy commands, one for the binaries and one for the content:
    <Target Name="MyPostBuildTarget">
    <Copy SourceFiles="@(MyCopyItems)"
    DestinationFiles="@(MyCopyItems->'$(MyOutputFolder)$(OutputSubFolder)%(RecursiveDir)%(Filename)%(Extension)')" />
    <Copy SourceFiles="@(MyCopyBin)"
    DestinationFolder="$(MyOutputFolder)bin" />
    </Target>
  4. I added this target to the BuildDependsOn property so that it is executed everytime the project is built:
    <BuildDependsOn>$(BuildDependsOn);MyPostBuildTarget</BuildDependsOn>

This gives something like:

<!-- Copy project output to defined folder -->
<PropertyGroup>
<BuildDependsOn>$(BuildDependsOn);MyPostBuildTarget</BuildDependsOn>
<MyOutputFolder>C:ProjectOutputFolder</MyOutputFolder>
<OutputSubFolder>SubFolder</OutputSubFolder>
</PropertyGroup>
<ItemGroup>
<MyCopyItems Include="$(MSBuildProjectDirectory)***.aspx" />
<MyCopyItems Include="$(MSBuildProjectDirectory)***.htm?" />
<MyCopyItems Include="$(MSBuildProjectDirectory)***.js" />
<MyCopyItems Include="$(MSBuildProjectDirectory)***.gif" />
<MyCopyItems Include="$(MSBuildProjectDirectory)***.jp?g" />
<MyCopyItems Include="$(MSBuildProjectDirectory)***.png" />
<mycopybin include="$(MSBuildProjectDirectory)bin***.dll" />
</ItemGroup>
<Target Name="MyPostBuildTarget">
<Copy SourceFiles="@(MyCopyItems)"
DestinationFiles="@(MyCopyItems->'$(MyOutputFolder)$(OutputSubFolder)%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="@(MyCopyBin)"
DestinationFolder="$(MyOutputFolder)bin" />
</Target>

Some references on copying project files with MSBuild:
MSDN MSBuild Reference – Copy Task
Channel 9 Wiki: Copy Built Output Of A Visual Studio Project
SharpDevelop Community – Copy config post build
How To: Insert Custom Process at Specific Points During Build
How To: Add Custom Process at Specific Points During Build (Method #2)