Introduction
Working on a large application can uncover some unique issues. Learning how everything is organized, built, referenced and such - can be challenging to say the least. In my experience with such an application, I came across an issue with using oost-build events, but only when using MSBuild. Because of the way the applications were built and organized, I had to add a post-build event to a particular project to copy the target “DLL” to a directory further up the folder hierarchy. In my case - when adding a Unit Test - you had to reference the “project under test” from one of the top-level directories - instead of from the “bin/Debug” folder. This was because the “Unit Test” project was referenced by many different Visual Studio solutions. Unfortunately, this also meant that changes to the project under test would not be seen by the Unit Test, until the newly built “DLL” was copied to the top-level folder where it is referenced by the Unit Test.
It’s a simple enough problem to fix; adding a simple “copy” command to the “Post-build event command” on the project under test does the trick:
copy /y $(TargetFileName) "..\..\..\..\Binaries\"
This works as expected when you build a solution or project from within Visual Studio. However, it broke the full application build. To understand why, you need to know that whatever you put in the “Post-build event command” textbox basically gets put into a batch file - and executed from the project’s “bin/Debug” folder (or bin/Release, depending on your configuration).
You can see that the command listed above will copy the “TargetFileName
” into a “Binaries” folder that is located four folders above the current directory. However, when we run the MSBuild build, it is executed from a different directory… which means that all of the post-build events that exist in any of the projects being built will be executed from that directory as well.
This causes an error in the MSBuild output because the Post-build event command cannot find the “Binaries” folder in the specified location.
However, we can workaround this problem, and essentially ignore the post-build event while running MSBuild. Remember that the Post-build event command is really just a place to put DOS commands that get executed after a successful build. This means that we can use some DOS variables. First, if you’re not starting the MSBuild process using a batch file already, create a batch file that calls the MSBuild process. Then, add a variable in the batch file before you call the MSBuild process. Something like this:
set ISFULLBUILD=True
msbuild TFSBuild.proj >> BuildOutput.txt
Then, you need to modify your post-build event to only do something if the variable is not set, or has the wrong value:
IF NOT '%ISFULLBUILD%'=='True' copy /y $(TargetFileName) "..\..\..\..\Binaries\"
That’s it! The TargetFileName
(Whatever.dll) will only get copied when you’re building from within Visual Studio. But, when you build using your new batch file - it will not execute the command after the IF
statement.