18

I have been studying MSBuild as I have the need to automate my development shop's builds. I was able to easily write a .BAT file that invokes the VS command prompt and passes my MSBuild commands to it. This works rather well and is kinda nifty.

Here is the contents of my .BAT build file:

call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\amd64\vcvars64.bat"
cd  C:\Sandbox\Solution
msbuild MyTopSecretApplication.sln /p:OutputPath=c:\TESTMSBUILDOUTPUT /p:Configuration=Release,Platform=x86
pause

^ This works well but I now have the need to use the MSBuild task for TeamCity CI. I have tried to write a few MSBuild scripts but I cannot get them to work the same. What is the equivalent build script to the command I am using in my .BAT file? Any ideas?

I have tried using something like this, but no success (I know this is wrong):

<?xml version="1.0"?>
<project name="Hello Build World" default="run" basedir=".">

<target name="build">
    <mkdir dir="mybin" />
    <echo>Made mybin directory!</echo>

  <csc target="exe" output="c:\TESTMSBUILDOUTPUT">
    <sources>
      <include name="MyTopSecretApplication.sln"/>
    </sources>
  </csc>
  <echo>MyTopSecretApplication.exe was built!</echo>
</target>

<target name="clean">
    <delete dir="mybin" failonerror="false"/>
</target>

<target name="run" depends="build">
  <exec program="mybin\MyTopSecretApplication.exe"/>
</target>

What I simply need is an MSBuild XML build script that compiles a single solution for Release mode to a specified output directory. Any help?

D3vtr0n
  • 2,774
  • 3
  • 33
  • 53

3 Answers3

29

Use the MSBuild task to build the solution passing the properties you need.

<?xml version="1.0" encoding="utf-8"?>
<Project
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
    ToolsVersion="4.0"
    DefaultTargets="Build">

    <PropertyGroup>
        <OutputDir>c:\TESTMSBUILDOUTPUT</OutputDir>
    </PropertyGroup>

    <ItemGroup>
        <ProjectToBuild Include="MySecretApplication.sln">
            <Properties>OutputPath=$(OutputDir);Configuration=Release</Properties>
        </ProjectToBuild>
    </ItemGroup>

    <Target Name="Build">
        <MSBuild Projects="@(ProjectToBuild)"/>
    </Target>

</Project>
Brian Walker
  • 8,658
  • 2
  • 33
  • 35
  • Thanks a million. Now if I have a project in "MySecretApplication.sln" that I want to exclude, how can I do that? I tried this but it isnt working...any ideas? – D3vtr0n Feb 25 '11 at 22:57
  • 3
    You would need to setup a build configuration in your solution (right-click on the solution node and choose Configuration Manager in Visual Studio). You can create a new configuration, give it a name, and select which projects to build. This is stored in the solution file. In the MSBuild file in the answer pass the new Configuration name. You may currently have a Debug and Release configuration which are the standard names. – Brian Walker Feb 25 '11 at 23:25
  • I actually noticed that this script does not build my Web Projects. I have two web projects (which are pretty vital to the entire app) and they are no longer included in my output. What do I need to do to include my Web Projects? Any ideas? It worked for my .BAT file, but not this MSBuild script :( – D3vtr0n Feb 27 '11 at 05:33
  • I am not seeing any special options or flags/tags/arguments to specify WEB projects? Its weird because the command line version builds it, but the MSBuild script wont. Any ideas? – D3vtr0n Feb 28 '11 at 15:21
  • I tried a web project I have here and it is working. For a regular ASP.NET web project there is no project file, the project settings are kept in the solution file. I ran the msbuild script I posted against it and it built the web site as well as the supporting assemblies. If the configuration you are building set to build in the Configuration Manager in Visual Studio? It shows up with a name like "D:\..\WebSiteName\". If you are using ASP.NET MVC then you will have a project file. – Brian Walker Mar 01 '11 at 15:51
2

Here is my final MSBuild script:

<?xml version="1.0" encoding="utf-8"?>

<PropertyGroup>
    <OutputDir>C:\TESTMSBUILDOUTPUT</OutputDir>
</PropertyGroup>

<ItemGroup>
    <ProjectToBuild Include="MyTopSecretApplication.sln" >
        <Properties>OutputPath=$(OutputDir);Configuration=MSBuildRelease;Platform=x86</Properties>
    </ProjectToBuild>
</ItemGroup>

<Target Name="Build">
    <MSBuild Projects="@(ProjectToBuild)"/>
</Target>

As you can see, the main difference from Brian Walker's answer is the "Configuration" setting. Here it is set to "MSBuildRelease" instead of "Release", which I customized from within the .NET IDE. Follow the steps Brian suggested (right-click on the solution node and choose Configuration Manager in Visual Studio, add "NEW" configuration and remove/uncheck projects you want excluded.)

I have since uploaded this to my TEAMCITY server, and have automated my .NET build process with your help. Thanks so much to Brian Walker (a fellow Texan)...I'll buy you a beer!! CHEERS!!

D3vtr0n
  • 2,774
  • 3
  • 33
  • 53
0

I know this isn't a direct answer to your question, but why not just use the built in Visual Studio build runner and pick up the compiled output from the appropriate /obj path and save it as a build artefact? If you're effectively not doing anything beyond a simple compile against a specified build configuration then there's not much value added by having a dedicated build file and using build artefacts can make a life a whole lot easier (use them in other builds, download them easily, etc).

Try the configuration described here if this isn't making sense: http://www.troyhunt.com/2010/11/you-deploying-it-wrong-teamcity_25.html

Troy Hunt
  • 20,345
  • 13
  • 96
  • 151
  • Essentially that is the same thing. Very interesting. The only difference I see is that with my XML build task script, I am able to use the CONFIGURATION parameter, to change my .SLN's build order. I dont see how to do that in Team City using this Auto Deploy/direct .SLN approach? – D3vtr0n Feb 27 '11 at 05:32
  • You can still pass this via the command line parameters field. As the description in TeamCity says "Enter additional command line parameters to MSBuild.exe". Easy! – Troy Hunt Feb 27 '11 at 22:20
  • Troy, do you know if this method will compile Web Projects easily? I am having a hard time building my ASMX files for release in my scripts. I need to convince myself that this is a viable option, worth investigating, but am curious if you know if it has web project limitations? cheers! – D3vtr0n Mar 01 '11 at 17:57
  • Sorry for any confusion. I am actually already using the VS.NET build runner in Team City. I wish I had seen your blog earlier when I set all this up and figured this all out myself, LOL. My build runner fails, because of the error posted above. It does not error when I compile locally, on my dev machine with the same exact build script Team City uses. I dont know why. – D3vtr0n Mar 01 '11 at 23:44
  • 1
    I also do not have Visual Studio licensed/installed on the build server. I did install VS.NET Express but am unsure if that's going to cut it. – D3vtr0n Mar 01 '11 at 23:45
  • Firstly, you shouldn't need Visual Studio installed on the build server (although it is a bit contentious). Have a read of the last paragraph under the "Hitting the right target" in the link in my answer. I'm not sure specifically what your error is but if you're talking about a web application and you don't have Visual Studio installed on the server and you haven't copied over Microsoft.WebApplication.targets, that might be your problem. Refer back to my blog on this one. Does it still fail after this? – Troy Hunt Mar 02 '11 at 01:27