Q:

How to get Visual Studio build process to create a distributable directory?

I would like to customize my Visual Studio Solution build to automatically create a directory tree with dist -> bin directories.  The bin directory should have all binaries automatically copied to it. 
Note: the solution has many projects so I do not want to customize the project build, this should be on the solution level.
I have already tried 2 solutions:
1) Modify each project file to create this dist directory tree if it does not already exists.  This seems redundant for me to be required to modify the project file for each new project added to the solution.
2) Created solution .targets files for use with msbuild.exe through the command line.  This worked exactly as I wanted but I prefer a solution that works within visual studio.
If anyone cares, the motivation is to have an easy way to distribute new builds without having to extract the source from them every time. 
Update: 5/26/15
I wanted to post my solution here so people with the same issue will have a solution.  I ended up creating an ImportBefore directory in the same directory as my solution file.  In the same directory as the solution there is a directory for each project contained in the solution. This is the standard structure for a visual studio solution and the structure is important as msbuild only has a reference variable for each project.
Place a file with the following content in $(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\$(MSBuildThisFile)\ImportBefore\ 
On my machine it is at C:\Program Files (x86)\MSBuild\12.0\Microsoft.Common.Targets\ImportBefore
My file "importbefore.targets" looks like this:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <ImportPath Condition="'$(ImportPath)'==''">$(MSBuildProjectDirectory)\..\ImportBefore</ImportPath>
  </PropertyGroup>

  <Import Project="$(ImportPath)\*" Condition="'$(ImportByWildcardBeforeMicrosoftCSharpTargets)' == 'true' and exists('$(ImportPath)')"/>

</Project>

To test that this was working I added the following target file to \ImportBefore or on my computer C:\Users\admin\Dropbox\Projects\BuildTestProject\ImportBefore
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="OnlyIfExists" BeforeTargets="Build" Condition="Exists('$(ImportPath)')">
    <Message Text="Found import directory '$(ImportPath)'" Importance="high" />
  </Target>
</Project>

In the end I will update the project file local to the solution to create a distribution directory only if it is not created and then copy the binaries for the current project that is being built to that distributable directory.

A:

There is some additional setup that is required, but once you have it setup, it works for all solutions\projects.
If you look at the Microsoft.Common.Targets (found in the C:\Windows\Microsoft.Net\Framework(MSBuildVersion)) you will see that it tries to import a number of custom targets files.  You can place your own targets file in the $(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\$(MSBuildThisFile)\ImportBefore\ folder or you can create a Custom.Before.Microsoft.Common.targets file in the $(MSBuildExtensionsPath)\v$(MSBuildToolsVersion) folder.  In your custom extension you can add an Import of $(SolutionDir)Solution.targets that has your custom copy command.  Since the Microsoft.Common.Targets file is used in both C# and C++ compiles, your custom targets will be loaded by all project types.  As long as you set these files up on all PC's that you use, you should be OK.
Another option is to just create a {Your Project Name and extension}.user file with your custom commands.  This solution does not require modification to the MSBuild folders, but does require each project to have their own file.  That said each .user file could load a $(SolutionDir)\Common.Targets file that had the copy commands in it.
In any case, I would just look at the Microsoft.Common.Targets file to see what it is doing.  If you look at the csproj file itself in a text editor you can see where it is importing Microsoft.Common.Targets.  This will help you better understand the MSBuild process all around.

