Thursday, December 25, 2014

Using the CallTarget Task to pass different parameters in MSBuild

If you have a task in MSBuild that you want to re-use over and over again similar to how you would call a function/method in a programming language such as C#, it is not readily obvious how to accomplish this in MSBuild.

Fortunately, there is a way to accomplish this using MSBuild and the CallTarget Task though the solution is not readily obvious.

  1. First of all, declare a set of Properties in a PropertyGroup that you want to use as parameters to your Target.  It is important that these Properties be declared globally in your MSBuild file so that the Target is always aware of the different values of your Properties.  If the Properties are declared locally to your Target then they will not be available across multiple calls to your Target.
  2. Next, declare your Target that you will need to call multiple times.  Within the Target, utilize the Properties that you defined in your global PropertyGroup.
  3. Finally, declare another Target which will be responsible for calling your Target using the CallTarget task multiple times.  In this Target, you will override the values defined in the Global Property between consecutive calls to your Target.
Therefore, your final MSBuild file will look like the following:

 
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath32)\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks" />
  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
  <PropertyGroup>
    <AdvancedInstallerPath>$(ProgramFiles)\Caphyon\Advanced Installer 11\bin\x86\AdvancedInstaller.com</AdvancedInstallerPath>
    <AdvancedInstallerProjectFilePath>Sample.aip</AdvancedInstallerProjectFilePath>
    <PathVariableName>Infragistics_Dir</PathVariableName>
    <PathVariableValue>$(PrerequisitesFilesDir)\Infragistics</PathVariableValue>
  </PropertyGroup>
  <Target Name="TestBuildPathVariables">
    <PropertyGroup>
      <PathVariableName>MyPathVariable</PathVariableName>
      <PathVariableValue>$(PrerequisitesFilesDir)</PathVariableValue>
    </PropertyGroup>
    <CallTarget Targets="PathVariableTarget" />
    <PropertyGroup>
      <PathVariableName>MyPathVariable2</PathVariableName>
      <PathVariableValue>$(PackagingFilesDir)</PathVariableValue>
    </PropertyGroup>
    <CallTarget Targets="PathVariableTarget" />
  </Target>
<Target Name="PathVariableTarget">
    <ItemGroup>
      <PathVariableArg Include="/edit" />
      <PathVariableArg Include="&quot;$(AdvancedInstallerProjectFilePath)&quot;" />
      <PathVariableArg Include="/NewPathVariable" />
      <PathVariableArg Include="-name $(PathVariableName) -value $(PathVariableValue) -valuetype Folder" />
    </ItemGroup>
    <Message Text="This is the command to be run: $(AdvancedInstallerPath) @(PathVariableArg, ' ')" />
    <Exec Command="&quot;$(AdvancedInstallerPath)&quot; @(PathVariableArg, ' ')" />
</Target>
</Project>

1 comment:

  1. I'm not sure if it will work, ms build won't build same target multiple times

    ReplyDelete