How to set the “default” configuration for a project.

Being a Process Consultant specializing in TFS I teach many companies how to use Team Build.  When you create a new build definition you have the option to set “Configurations to Build”. However, if you leave that value blank the build will build the “default” configuration. The questions I am inevitability ask are “what is the default configuration” and “how do we set the default configuration”?  Well in this post I will show you where it is stored and how to update it for typical Visual Studio 2012 project. Visual Studio projects are msbuild scripts and because of that we can set properties in the actual project files that are going to be sent to msbuild to be compiled.  To change the default configuration you we need to load the project file as xml which is the file format of msbuild.  With the project open in Visual Studio simply right click on the desired project and select “Unload Project” from the context menu.  Once the project is unloaded right click on it again and select “Edit [Project Name]” and Visual Studio will open the file as an xml file we can edit.  Search the file for a “Configuration” element in a property group (it is normally the first group).  It should look similar to this: <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>   This is the line responsible for setting the default configuration of your build.  Simply change “Debug” to the desired default configuration, save the file then right click on project file in Solution Explorer and select “Reload Project”.  After you check in your changes an queue a new build it will be built using this configuration if the “Configurations to Build” is blank in the build definition.

Team Foundation Build Configuration - HTTP code 500

Problem:  After adding host headers to my TFS Website in IIS my build server fails to connect with the following error:   Solution: Add multipleSiteBindingsEnabled=true  to the serviceHostingEnvironment element in the C:\Program Files\Microsoft Team Foundation Server 11.0\Application Tier\Message Queue\web.config file on the application tier machine. Explanation: We added host headers to the TFS Website so users would not have to type in the port to reach web access.  After doing so our build would continue to fail.  Updating the web.config corrects the error and allows builds to run.

Cannot register assembly during Team Build (and I don't want too)

Problem: I have a solution that contains a project with the "Make assembly COM-Visible" checked and I get the following error when I attempt to run a team build: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.Common.targets (3885): Cannot register assembly "C:\Builds\1\TeamProject\Libraries - CI\bin\Debug\Mydll.dll" - access denied. Please make sure you're running the application as administrator. Access to the registry key 'HKEY_CLASSES_ROOT\Mydll' is denied. Solution: Pass "/p:RegisterForComInterop=false" to MSBuild using the MSBuild Arguments process parameter of your build definition. Explanation: The service account running my build agent is not an adminstrator on my build.  Therefore; it does not have permissions to write to the registry to register the COM assembly.  Because this is my build machine I have no desire to have the COM assembly registered on this machine. I simply what the solution to build. When the "Make assembly COM-Visible" is checked the project file is changed to include a target to register the assembly. That target has a condition testing if RegisterForComInterop is true.  By passing the values to MSBuild you are overriding the default value of True with False.  This will allow the project to compile and skip the step to register.

Build workspace folder already mapped.

Problem: My Team Build keeps failing with an error that my source folder is already mapped in another workspace. The path C:\Builds\1\Demo\Reports\Sources is already mapped in workspace 7_1_WIN-GS9GMUJITS8. Solution: Use the tf.exe tool to delete the workspace holding on to that location. Explanation: tf workspace /delete [/collection:TeamProjectCollectionUrl] workspacename[;workspaceowner] [/login:username,[password]]

How to enable code coverage in my Team Build

Problem: I am not getting code coverage results in my build. Solution: Ensure you have a test settings file selected in your build definition. Explanation: On the process tab of your build definition expand the Automated Testing section under Basic and make sure the TestSettings File is pointing to the test settings file that has code coverage configured. You can watch a video below that demonstrates how to do this.

How to Xcopy deploy using TFS 2010/2012

Problem I need my VS2010/VS2012 build to perform an “Xcopy deployment” of my ASP.NET application to an existing virtual directory. Solution Customize the build template to use the CopyDirectory activity to copy the ASP.NET application to the virtual directory. Explanation One of the benefits of ASP.NET development is the simply “Xcopy deployment”. ASP.NET applications require no changes to the registry and have no special installation requirements for the hosting server.  Therefore, you can use the drag-and-drop feature in Microsoft Windows Explorer, File Transfer Protocol (FTP), or the DOS Xcopy command to copy files from one computer to another. The only prerequisite of this technique is the virtual directory in IIS must already be created and configured. The goal of this build is to not have to install any special features or extensions in IIS to facilitate deployment of my ASP.NET application.  I want my environments to match production as close as possible and I never intend on installing IIS Extensions in production. When you configure a build definition that builds and ASP.NET application the binaries directory and drop location contain a folder named _PublishedWebsites.  Each ASP.NET application built during the build will have a sub directory that contains all the files needed for the application. To perform an “Xcopy deployment” we simply need to identify the source and destination directories.  We are going to store this information in arguments passed to the build.  To begin open the DefaultTemplate.xaml file in VS2010 and click the Arguments button at the bottom of the workflow designer to show the workflow arguments.  Add two string arguments  VDir and SiteDir. Now let’s add a nice coat of polish on our arguments.  Click the ellipses next to the default value of the Metadata argument to show the Process Parameter Metadata Editor window.  Click the Add button and enter in the following information and click OK. Parameter Name – VDirDisplay Name – Virtual DirectoryCategory – DeployDescription – The full UNC path to the virtual directory to copy the website too. Editor – leave blankRequired – leave unchecked View this parameter when – Always show the parameter and Parameter Name – SiteDirDisplay Name – Site DirectoryCategory – DeployDescription – The sub directory of _PublishedWebsites to copy from.Editor – leave blankRequired – leave uncheckedView this parameter when – Always show the parameter   We are simply going to add a CopyDirectory activity that uses the arguments we just created to perform the copy.  To begin we must locate the correct area of the build template to add our CopyDirectory activity.  I find the quickest way to do this is to click the Collapse All button at the top of the workflow designer window.  Now double click on the words Double-click to view on all of the following activities: 1.    Run On Agent2.    Try Compile, Test, and Associate Changesets and Work Items 3.    Sequence4.    Compile, Test, and Associate Changesets and Work Items5.    Try Compile and Test6.    Compile and Test7.    For Each Configuration in BuildSettings.PlatformConfigurations8.    Compile and Test for Configuration When we configured the metadata for our arguments we left the Required checkbox unchecked.  This will allow users of this build template to leave the values for VDir and SiteDir blank if they are not building an ASP.NET application or simply do not want to deploy them.  Therefore, we need to check the value of the arguments to determine if we need to perform the copy or not.  In the toolbox expand the Control Flow tab and drag and drop the If activity right above the If Not Disable Test activity.  Click the double down arrows in the title bar of the if to show its contents. In the Condition text box enter the following: Not String.IsNullOrWhiteSpace(VDir) From the toolbox drag and drop a Sequence activity from the Control Flow tab onto the Then side of the If.  Change the DisplayName of the sequence to Deploy ASP.NET Application. We add a sequence here so that we can use multiple activities. Click the double down arrows in the title bar of the sequence to show its contents.  This is where we are going to add the activities needed to copy the ASP.NET application to the virtual directory in IIS. Now we can add the CopyDirectory activity and set the properties to deploy our ASP.NET application during the build.  To get started simply drag and drop the CopyDirectory activity from the Team Foundation Build Activities tab into the Deploy ASP.NET Application sequence.  With the CopyDirectory activity selected set the following values in the properties window: •    Destination – Vdir•    Source  - BinariesDirectory + "\_PublishedWebsites\" + SiteDir Now save your xaml file, check in your changes and queue a new build. You can download a copy of the final file below. TFS2010 DeployTemplate.xaml (55.16 kb) TFS2012 DeployTemplate.11.1.xaml (75.68 kb)

I need to build a project that is not supported by MSBuild

Problem My solution contains a .vdproj and it is not supported by MSBuild. Solution Call devenv from team build using InvokeProcess for .vdproj projects. Explanation This customization can be extended to build any project types not supported by MSBuild (vb6, power builder, fortran, VC++ 6, etc).  Any project that can be built from the command line can also be built using TFS 2010 Build using this technique. We are simply going to add a switch statement that uses the extension of the project to determine if we pass it to MSBuild or perform the build ourselves.  Let’s start by opening DefaultTemplate.xaml from the BuildProcessTemplates folder.  To begin we must locate the correct area of the build template to add our switch statement.  I find the quickest way to do this is to click the Collapse All button at the top of the workflow designer window.  Now double click on the words Double-click to vew on all of the following activities: 1.    Run On Agent2.    Try Compile, Test, and Associate Changesets and Work Items 3.    Sequence4.    Compile, Test, and Associate Changesets and Work Items5.    Try Compile and Test6.    Compile and Test7.    For Each Configuration in BuildSettings.PlatformConfigurations8.    Compile and Test for Configuration9.    If BuildSettings.HasProjectsToBuild10.    For Each Project in BuildSettings.ProjectsToBuild11.    Try to Compile the Project12.    Compile the Project The Compile the Project Sequence contains the Convert Server Path to Local Path and Run MSBuild for Project activities.  We are going to add our switch around Run MSBuild for Project.  In the toolbox expand the Control Flow tab and drag and drop the Switch<T> activity right above the Run MSBuild for Project activity.  When prompted for type, select String and click OK. Our switch is going to test the extension of the current project being built. If the extension is .vdproj we are going to call devenv ourselves to build the setup project.  If the extension is anything else we are going to simply let MSBuild build it.  So the first thing we need to do is find the extension of the project being built.  The Convert Server Path to Local Path activity stores the project path in localProject which we can use to find the extension.  Click the double down arrows in the title bar of the Switch<String> activity to show the expression and cases of the switch.  In the Expression text box enter the following: (New System.IO.FileInfo(localProject)).Extension.ToLower()This line of code uses an instance of the FileInfo class to gain access to the extension of the current project being built.  We call ToLower to make sure the case of the extension is known for our comparison.Now click the word Default to display the activity area of that case.  Drag the Run MSBuild for Project into the default case. At this point the template works exactly as it did before we touched it. After our customizations you will still be able use this template for all your current builds that use the default template. Now it is time to add the case for the .vdproj projects. Click the words Add new case. In the Case Value combo box type .vdproj without ”’s.  The switch already knows that what you are going to type is a string so you DONOT type the “’s.  If you do it will fail because “.vdproj” is not equal to .vdproj. From the toolbox drag and drop a Sequence activity from the Control Flow tab onto the .vdproj case.  Change the display of this sequence to Build Setup Project.  We add a sequence here so that we can use multiple activities. Click the double down arrows in the title bar of the sequence to show it's contents.  This is where we are going to add the activities needed to build the setup projects. Before we can add the InvokeProcess activity to build the setup projects we first need to know the command line.  Below is an example of the command line to build a setup project.  Notice we must provide the configuration to build "C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\devenv" "C:\Builds\1\Build Sandbox\HelloWorld\Sources\HelloWorld\Setup\Setup.vdproj" /build Release Now we can add the InvokeProcess activity and set the properties to build this command line during the build.  To get started simply drag and drop the InvokeProcess activity from the Team Foundation Build Activities tab into the Build Setup Project sequence.  With the InvokeProcess activity selected set the following values in the properties window: •    Arguments - """" + localProject + """ /build " + platformConfiguration.Configuration•    FileName - """C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\devenv""" The rest of the values can remain with their default values.  Pay close attention to the number of “’s and white space.  Because localProject may contain spaces we must quote the string. The same is true for the path to devenv.exe.  Whenever I use an InvokeProcess activity I always expand it and add a WriteBuildMessage under Handle Standard Output with the Message set to stdOutput and a WriteBuildError under Handle Error Output with the Message set to errOutput.  This will allow that information to be show in the build output.  At this point if we check in our changes and add our .vdproj file as an Items to Build from the Process tab of the build definition the setup project will be built.  Be sure and remove the .vdproj project from the solution or you will continue to get errors from MSBuild. However, it will not be in our drop location.  The reason for this is because only items that are in the binaries folder get copied to the drop location.  The final piece is to add a CopyDirectory activity under the InvokeProcess to copy the contents of the output folder of the setup project to the binaries folder. With the CopyDirectory activity selected set the following values in the properties window: •    Destination - BinariesDirectory•    Source - (New System.IO.FileInfo(localProject)).DirectoryName + "\" + platformConfiguration.Configuration + "\" Your Build Setup Project sequence should look like this:  Now save your xaml file, check in your changes and queue a new build. You can download a copy of the final file below. TFS2010 DefaultTemplate.xaml (59.14 kb) TFS2012 DefaultTemplate.11.1.xaml (81.14 kb)

My build agent just stopped working!

Problem My build agent state in Team Foundation Administrative Console states Ready but the icon shows stopped and I can't queue builds. Solution Either log in as the Service Account used to run the build agent or log in using any account and right click on IE and run as the Service Account.1. Open Internet Explorer and go to Tools –> Internet Options2. Choose the Connections tab3. Click the “LAN settings” button4. Uncheck the “Use a proxy server for your LAN” checkbox.  Explanation One of my builds collects code coverage results on a web application.  To do so the IE connection settings are configured to use a proxy while the data is collected and then returned to the original configuration afterwards.  However, if you are forced to stop a build the proxy will stay configured and lead to this problem. The key is to log in or run IE as the Service account to uncheck the proxy check box on the connection setting of IE.

My build keeps hanging on the psexec call

Problem Calling psexec from an invoke process activity on a 2008 Server and it is hanging. Solution Upgrade to 1.98 of psexec and use the -h switch to run with the account's elevated token. Explanation If the target system is Vista or higher, the -h allows the process to get past the UAC that is preventing the application from running as expected. PSTools