- | rssFeed | My book on MSBuild and Team Build | Archives and Categories Sunday, July 29, 2012

MSBuild how to execute a target after CoreCompile part 2

A couple of months ago I wrote a blog post MSBuild how to execute a target after CoreCompile in which I describe how you can execute a target if the CoreCompile target is executed, if CoreCompile is skipped then so will your other target. The draw back of the approach that I outlined in my previous post was that it required you to edit your .csproj/.vbproj/etc file itself. So if you had a scenario where you were building multiple projects then you would have to edit all of the project files. In this post I’ll describe how you can perform the same customization without having to edit the project file itself. Note this blog is in response to a question on StackOverflow Determine if MSBuild CoreCompile will run and call custom target.

Before we get to the solution for this particular case let me describe an extensibility hook that the C# and VB projects have. Most of the logic for building C# and VB projects is captured in the MSBuild targets file at C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets. If you take a look in that file you will notice at the top an import looking like the one below.

<Import Project="$(CustomBeforeMicrosoftCommonTargets)" Condition="'$(CustomBeforeMicrosoftCommonTargets)' != '' and Exists('$(CustomBeforeMicrosoftCommonTargets)')"/>

This statement will import a file (located at the value for CustomBeforeMicrosoftCommonTargets) if the property is not empty and the file exists. The default value for CustomBeforeMicrosoftCommonTargets is C:\Program Files (x86)\MSBuild\v4.0\Custom.Before.Microsoft.Common.targets. So if you drop an MSBuild file at that location it will modify the build process for every C#/VB project built on that machine. Alternatively if you do not want (or cannot due to ACLs) then you can drop the file somewhere else and then specify its location by overriding the CustomBeforeMicrosoftCommonTargets property. This is the approach that I will take here. I have created a sample solution which consists of two projects ProjA and ProjB. I also have a build script, build.proj, to automate the build for this. Below is the entire contents of build.proj.

build.proj

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <FileToInject Condition=" '$(FileToInject)'=='' ">$(MSBuildThisFileDirectory)extend-corecompile.proj</FileToInject>
  </PropertyGroup>

  <ItemGroup>
    <ProjectsToBuild Include="ProjA\ProjA.csproj"/>
    <ProjectsToBuild Include="ProjB\ProjB.csproj"/>
  </ItemGroup>

  <Target Name="Build">
    <MSBuild Projects="@(ProjectsToBuild)"
             Properties="CustomBeforeMicrosoftCommonTargets=$(FileToInject)" />   
  </Target>

  <Target Name="Clean">
    <MSBuild Projects="@(ProjectsToBuild)" Targets="Clean"/>
  </Target>

  <Target Name="Rebuild" DependsOnTargets="Clean;Build"/>
  
</Project>

In the Build target above I use the MSBuild task to build both ProjA and ProjB. As you can see I am passing the property CustomBeforeMicrosoftCommonTargets=$(FileToInject) which points to extend-corecompile.proj. By passing this property when ProjA, and ProjB, is built it will automatically import the extend-corecompile.proj file for the build process. You can see the contents of extend-corecompile.proj below.

extend-corecompile.proj

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <TargetsTriggeredByCompilation>
      $(TargetsTriggeredByCompilation);
      MyCustomTarget
    </TargetsTriggeredByCompilation>
  </PropertyGroup>

  <Target Name="MyCustomTarget">
    <Message Text="MyCustomTarget called" Importance ="high"/>
  </Target>
  
</Project>

This project file uses the technique outlined in my previous blog post to execute the MyCustomTarget only if CoreCompile is executed.

Note: You can get the latest version of this sample at https://github.com/sayedihashimi/sayed-samples/tree/master/ExtBuildMultiple.

Sayed Ibrahim Hashimi | SayedIHashimi

msbuild Sunday, July 29, 2012 12:27:47 AM (GMT Daylight Time, UTC+01:00)  #     | 
Thursday, July 12, 2012

Visual Studio 2012 RC Web Tooling Extensions update

If you have been following our blog and twitter accounts then you most likely have heard that some of the Web components of Visual Studio 2012 are now “Out of Band”. What that means is that we can update those components separately from Visual Studio itself. Because of this we will be posting updates on a regular basis. Today marks the first of these updates, and its targeting Visual Studio 2012 RC. In this post I will describe how to get the update and then what the update contains.

How to get the update

If you already have Visual Studio 2012 RC installed when you launch VS you will see a notification in the task tray like the image below.

image

Note: VS checks for updates once a day so if you don’t see this notification today its likely that the check has already been performed

After you click on the notification you will be brought to the Extension and Updates dialog. To get the web updates you should go to the Visual Studio Gallery tab and then click Update on the Web Tooling Extensions item.

image

After installing the update you will need to restart VS.

What is contained in the update

The goals that we had when creating this update mainly consisted of.

  1. Fix key customer reported bugs which we didn’t have time to complete for the RC release
  2. Test out the update mechanism publicly

Since the intent of this release was not to light up any new features you won’t find any new functionality, but you may discover that an issue you are running into has been fixed. Most of the bugs which we fixed were filed by customer on Microsoft Connect, though some came in through other channels. For the Connect bugs you will see a link to the bug details, for Connect bugs filed as private there will not be a link. Below you will find a list of the fixed bugs as well as a brief description of the bug.

Web publishing raises an exception due to <connectionStrings> content

If the root web.config contained elements under <connectionStrings> that did not have a name attribute an exception was raised.

Reported Bugs

 

Web publish to the File system doesn’t always include all files

When publishing a web project to the file system there are cases where files are not getting updated on publish.

Reported Bugs

Web publish doesn’t handle read-only profiles correctly

In certain cases if a web publish profile is read-only it can cause VS to crash.

Reported Bugs

Web publish doesn’t include all files if there is no project configuration matching the solution configuration

The drop down for Configuration on the publish dialog was mapped to Solution Configurations instead of Project Configurations. Because of this if a Solution Configuration was selected which did not have a corresponding Project Configuration the files would not be published. We have updated the dialog to show the correct value.

Reported Bugs

Wrap up

We are really excited to be able to publish updates on a more regular basis and we hope that you will find that helpful as well. In case you guys were wondering if we listen to feedback/Connect bugs I hope that this post helps to show that we are listening to feedback and working to resolve bugs which get filed on Connect. Keep filing the bugs so that we can make our product even better. If you have already filed bugs on Connect then Thank You!


Sayed Ibrahim Hashimi | @SayedIHashimi

Visual Studio | Visual Studio 2012 | Web Development | Web Publishing Pipeline Thursday, July 12, 2012 8:01:03 PM (GMT Daylight Time, UTC+01:00)  #     |