If you have a project file that imports our .TARGETS files ... for example,
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
...
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets"/>
</Project>
and you want to invoke some of your own tasks that have the same class name as our tasks, but you want to do it in a way that does not cause Microsoft.Common.targets to start invoking your tasks, then you need to fully qualify your task name in the
<UsingTask> tag. Furthermore, when intending to invoke your own task, you need to call it using something other than the simple name. For example:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
[<UsingTask] TaskName="My.Override.Tasks.AssignCulture" AssemblyName="..."/>
<Target Name="AfterBuild">
<!-- Both of these will invoke the Override task ... -->
[<My.Override.Tasks.AssignCulture] ... />
[<Override.Tasks.AssignCulture] ... />
<!-- But this will invoke the [MSBuild] team's task ... -->
[<AssignCulture] ... />
</Target>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets"/>
</Project>
The reason we did it this way is because it is also a scenario for us to enable people to truly override our tasks with their own, in a way that causes even Microsoft.Common.targets to start invoking the customer's task instead of the one we ship (without having to modify Microsoft.Common.targets). You would achieve this scenario by registering the simple name in the
<UsingTask> tag.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
[<UsingTask] TaskName="AssignCulture" AssemblyName="My.Override.Tasks"/>
<Target Name="AfterBuild">
<!-- ALL of these will invoke the Override task ... -->
[<My.Override.Tasks.AssignCulture] ... />
[<Override.Tasks.AssignCulture] ... />
[<AssignCulture] ... />
<!-- But this will invoke the [MSBuild] team's task ... -->
[<Microsoft.Build.Tasks.AssignCulture] ... />
</Target>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets"/>
</Project>
Here's the search order that we use when we need to figure out which assembly to invoke a particular task from:
1.)
UsingTask tags in the project file or .TARGETS file that have a
TaskName attribute that matches exactly with the task name that is being invoked.
2.)
UsingTask tags in Microsoft.Common.tasks or other *.TASKS files that have a
TaskName attribute that matches exactly with the task name that is being invoked.
3.)
UsingTask tags in the project file or .TARGETS file that have a
TaskName attribute that partially matches with the task name that is being invoked.
4.)
UsingTask tags in Microsoft.Common.tasks or other *.TASKS files that have a
TaskName attribute that partially matches with the task name that is being invoked.