- | rssFeed | My book on MSBuild and Team Build | Archives and Categories Sunday, January 08, 2006

MSBuild CreateProperty bug workaround

Previously I posted about a bug in MSBuild that doesn't allow you to create a property (or item) and use this in a target that is invoked with the CallTarget task. There is a way to invoke the calling target with the new value of the Property and that is to use the MSBuild Task to achieve this. This task allows you to use MSBuild to execute a specified set of targets. Using this task you can also send a set of properties that you'd like for it to use when building the project. So to workaround our previous issue, you must use the MSBuild task and pass in the properties that you desire. Have a look at the workaround project file:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Create">
    <
Target Name="Create">

        <
CreateProperty Value="E:\Data">
            <
Output TaskParameter="Value" PropertyName="DestFolder" />
        </
CreateProperty>
        <
CreateItem Include="*.*">
            <
Output TaskParameter="Include" ItemName="TestFiles"/>
        </
CreateItem>

        <!-- This doesn't work, the property & item have no value in the print target -->   
        <
CallTarget Targets="Print"/>

        <!-- Using this we are able to pass the property but not the item value -->
        <
MSBuild
           
Projects="$(MSBuildProjectFile)"
           
Targets="Print"
           
Properties="DestFolder=$(DestFolder)"
       
/>
    </
Target>
   
    <
Target Name="Print">
        <
Message Text="Print target called"/>
        <
Message Text="Dest: $(DestFolder)"/>
        <
Message Text="TestFiles: @(TestFiles)"/>
    </
Target>

</Project>

Here is the output when you execute the default target (Create)

Project "C:\Data\Dreamcatcher_NET\Dreamcatcher\Sample_Workaround.proj" (default targets):

Target Create:
    Target Print:
        Print target called
        Dest:
        TestFiles:
    __________________________________________________
    Project "C:\Data\Dreamcatcher_NET\Dreamcatcher\Sample_Workaround.proj" is building "C:\Data\Dreamcatcher_NET\Dreamcatcher\Sample_Workaround.proj" (Print target(s)):

    Target Print:
        Print target called
        Dest: E:\Data
        TestFiles:

Build succeeded.
    0 Warning(s)
    0 Error(s)

That's kind of interesting how the property & item value are immediately available but not when you use the CallTarget task. At least you can get around the Property passing issue somewhat. There are some key limitations to this method, the most important of which is the fact that you must specify which properties to send to that target, and there is no way to send all the properties. And of course you can't send any items. The good thing about this issue is that I don't think this will impact a lot of people. You are not very likely to need this functionality, and there are ways around it. Namely if you use target dependencies you can execute the targets without the need to use the CallTarget task, but it would be convenient if it worked.
You can download the workaround file from the link below, if this doesn't fix your situation I'd be interested to know more about it. Maybe there is a way around it that does. Also I have updated the MSDN Product Feedback item, I added this workaround.

Sample_Workaround.proj (.73 KB)


msbuild | Visual Studio Sunday, January 08, 2006 5:53:12 AM (GMT Standard Time, UTC+00:00)  #     |