If you are familiar with the Team Build process in TFS2010, you can skip the background section.
As we know that in TFS2010, the team build leverages workflow instead of build scripts. We will also notice that TFSbuild.proj no longer exists. We can find the build template at the BuildProcessesFolder Open the DefaultTemplate.xaml, and expand the workflow. Then find the MSBuild activity Hit F4 or open the Properties Window. Notice the CommandLineArguments property. The value of that property is passed to MSBuild process as argument (i.e. MSbuild.exe /p:SkipInvalidConfigurations= true /p:referencepath=somepath …. Notice the MSBuildArguments in the value field. The MSBuildArguments is an Argument that is built into the Default Team Build template. If you click the Arguments button at the bottom, you will find it listed there. Those arguments are properties in your team build definition. Right click on the team build definition, click Edit Build definition
Select the Process tab from the left tab list. Notice that the Build process parameters are listed in the arguments list in the build template. Keep in mind, only the arguments with the “In” or “In/out” direction are visible to the process template
In a solution that contains many projects, it is normal to have a folder that contains common references to third party assemblies. Those assemblies can be custom controls, enterprise libraries, reusable libraries from other projects, ..etc. The Msbuild needs to have a reference to that folder to be able to compile the project or the solution. You need to keep in mind the following points:
- Team build downloads the latest files from source control every time team build is requested; custom assemblies need to be checked in
- The folder need to be visible to the teambuild workspace; in build definitionworkspace
- Typically you have multiple build agents whose working directory path is different from the development workstation and other build agents. In other words, you can’t pass an absolute path to msbuild
We want to pass a relative path as MSBuild argument i.e. MSBuild /p:referencepath=”$(SourceDirectory)\referenced assemblies\”. Team build template doesn’t out of the box convert $(SourceDirectory) to a physical path when passed as MsBuild argument
We need to modify the build template to replace $(SourceDirectory) with the source directory’s physical path.
- Add an If activity to check if the MSBuildArguments is null or empty. To keep things organized, I recommend adding the activity to the “Run on Agent”Initialize Variables. Make sure you add it at the end because the source directory is initialized in that block
- Add an Assign Activity to the Then block.
- Open the properties window
- Give the activity a more descriptive name
- In the To property, type MSBuildArguments
- In the value property, type MSBuildArguments.Replace(“$(SourceDirectory)”, SourcesDirectory). This is case sensitive.
- Save the template
- Check in the template
- Open an existing build definition or create a new one
- Go to the process section
- Expand the advanced section
- Enter /p:referencepath=”$(SourceDirectory)\Referenced Assemblies\\” in the MsBuild Arguments parameter, where “Referenced Assemblies” is the folder where your assemblies are saved. Don’t forget the quotes and the double slash that the end (i.e. \\). Thanks to Bernd who commented on the this post. I was able to confirm if you have spaces in your path you need to either add double slash at the end of the path or no slash characters at all (e.g. “$(SourceDirectory)\Referenced Assemblies”)
- Save the definition and queue a new build
- The following is a screen show of the log
When trying to run a Windows phone 7 code I got the following error “Zune software is not launched. Retry after making sure that Zune software is launched”. It turned out that I had Windows Phone 7 Device selected for deployment instead of the emulator
After selecting Windows Phone 7 Emulator, everything was working. How hard is it to have a better error message?
This post is in response to a question asked in the TFS Automated Build Forum: http://social.msdn.microsoft.com/Forums/en-US/tfsgeneral/thread/44de4e0a-fcc0-4874-a4af-804dc458f43f/#b0c4c0a3-758a-4204-ac4b-d4e1e93e2d75.
Smart Assembly is a product to obfuscate .NET assemblies and automated error reporting. For more information about the tool, you can visit http://www.red-gate.com/products/dotnet-development/smartassembly/
To answer the question in the MSDN forum, I downloaded and installed the trial version Smart Assembly from Red Gate’s website. There wasn’t anything tricky while installing the product and it was straight forward.
I had to create a smart assembly project (.saproj) file which is an xml file that contains all the features that need to be enabled and their configuration. Smart Assembly comes with its configurator which makes it really easy to configure the features to be used. The following is a screen shot of the configurator
Follow these steps to create a project
- Click New Project
- Click Browse Assembly button
- Select the file to be obfuscated, you want to select the dll or exe file located in the bin\release folder
- Click Set Destination button, the configurator doesn’t allow you to select the same destination file as the input one using the same folder (i.e. over write the input one)
- I have set the destination to be bin\SmartAssembly\SmartAssemblyPOC.exe
- Notice the toolbar, clicking on toolbar buttons auto scrolls to the respective section
- Check the assembly that you want to obfuscate
- Click Save project on the left list
- Save the saproj at the same directory where the project is saved. You can choose other location if you want to
- Test your project by clicking Build on the left
Usually we don’t have one project in a solution. Therefore it is not practical to open the smart assembly tool for every project and build it manually. Luckily, we can integrate building the smart assembly project while building the project using MSBuild.
I basically followed the instruction in this link;
- Right click on your project
- Unload the project
- Find the following line if you have a vb project
<Import Project=“$(MSBuildToolsPath)\Microsoft.VisualBasic.targets“ />
- Or this line if you are using C#
<Import Project=“$(MSBuildToolsPath)\Microsoft.CSharp.targets“ />
- Below the above line add the Smart Assembly targets
AssemblyName=“SmartAssembly.MSBuild.Tasks, Version=18.104.22.168, Culture=neutral, PublicKeyToken=7f465a1c156d4d57“ />
Condition=“ ‘$(Configuration)’ == ‘Release’ “>
- Save the project
- Load the project from solution explorer
- I will quickly explain what the above lines mean. The UsingTask element maps the AssemblyName to the TaskName. Version is the version number of the SmartAssembly. If you are using version 5, change the version number to 22.214.171.124. AfterBuild target is executed after the build is complete to obfuscate the smartassemblyPOC.exe in the release folder and then override it on the same folder. The $(OutDir) will be replaced by MSBuild with output folder of your assembly. The input and output in the MSBuild task overrides the input and output in the saproj
- Build the project in Visual studio to make sure it compiles and the assembly gets obfuscated
- It is not necessary to include the saproj file in the project as long as it is checked in. To include the saproj in the project:
- Check in your changes
- You need the SmartAssembly executable to be installed on your build machine otherwise Team Build won’t be able to find the SmartAssembly Tasks
After the Team build is done, view the log file
- Notice the execution of the SmartAssembly task