Multi-Targeting : How does it work?

So in my last post, I described the multi-targeting feature at a very high level. I discussed how there will be three frameworks that you can build “for”, and how there will be two toolsets – i.e. .NET Framework 2.0 / MSBuild 2.0 toolset, and the .NET Framework 3.5 / MSBuild 3.5 toolset.

Recall that the capability we have added to MSBuild as a part of this feature is the ability for you to take a project, and build it using either toolset. MSBuild 3.5 supports a new command line parameter known as ToolsVersion that allows you to specify which toolset you want to build using, and is invoked as shown:

msbuild WindowsApplication1.csproj /ToolsVersion:3.5

ToolsVersion is the parameter that you use to force a project to build using a specific toolset. There are only two toolsets available out of the box, but you can also set up “custom” toolsets depending on your needs, and MSBuild can be used to build projects using those that you have defined. More on that later.

So, the next question obviously is, what happens when you build a project using a specific ToolsVersion, and what are the mechanics in action behind the scenes?

To understand this, we have to know a bit about how our project files are described. A standard Visual Studio managed project includes an import statement like the one shown below that is responsible for pulling in all the MSBuild / managed code build process into the project:

<Import Project=$(MSBuildBinPath)\Microsoft.CSharp.targets />

In MSBuild 2.0 (Visual Studio 2005 release), $(MSBuildBinPath) evaluated to the location of MSBuild 2.0, i.e. the .NET Framework 2.0 install path. In order to import the new version of Microsoft.CSharp.targets, naturally this needs to change to location of Microsoft.CSharp.targets that ship along with MSBuild 3.5. So in essence, specifying a ToolsVersion value at the command line is essentially equivalent to choosing from a predefined set of valid values for $(MSBuildBinPath). So specifying a ToolsVersion of 2.0 will cause MSBuildBinPath to evaluate to the .NET Framework 2.0 install path, and 3.5 will cause it to evaluate to the .NET Framework 3.5 install path, etc. Additionally, the targets that ship in MSBuild 3.5 include enhancements to the build process that will cause it to use the new set of compilers and other tasks.

MSBuildBinPath has also been “deprecated” in favor of MSBuildToolsPath – new projects created will use MSBuildToolsPath since that is a better name for what the property represents.

Allowing you to specify which toolset to use is only half the story. Multi-Targeting is also about building your code “targeting” a specific version of the framework – for instance, you might want to build your app only so that it relies on 2.0 assemblies and not on any 3.0 or 3.5 assemblies. This is done using another lever that is available via your project file. You can include a property in your project file known as TargetFrameworkVersion that specifies which target framework you are building your application for. TargetFrameworkVersion can either be v2.0, v3.0 or v3.5 – this means that if you are referencing assemblies that are not in a given TargetFrameworkVersion, then you will get errors/warnings at build time that will tell you so. This prevents you from taking on dependencies that will surprise you when you later turn around and try to deploy your app in a more tightly controlled environment that might only have a smaller subset of the three frameworks installed. Since TargetFrameworkVersion is a new concept, you need to be using ToolsVersion 3.5 in order to succefully build projects while honoring the TargetFrameworkVersion property.

This is a confusing topic, so please feel free to ask questions, and provide feedback so that we can help clarify anything on the subject.

[ Author : Faisal Mohamood ]


Comments (15)

  1. Harris says:

    Since the TargetFrameworkVersion property only works with the 3.5 toolset, I take it this would fail:

    msbuild windowsapplication1.csproj /ToolsVersion:3.5 /property:TargetFrameworkVersion=v2.0

    If so, how would you target the 2.0 CLR and use the feature to ensure you only have references to 2.0 assemblies?  Or is the answer "you wouldn’t do that"?

  2. Buck Hodges says:

    Faisal Mohamood, a program manager on the MSBuild team , has written a pair of posts about the "multi-targeting"

  3. msbuild says:


    No – it is perfectly legal for you to build exactly like you are building. This indicates that you want to build using the 3.5 toolset, and that your application will be built to target the 2.0 version of the .NET Framework.

    The 3.5 toolset can build for v2.0, v3.0 and v3.5 frameworks. In all three frameworks, the core CLR itself is always 2.0 – it is just that there are libraries in v3.0 and v3.5 that don’t ship as a part of the .NET Framework 2.0. If you look at .NET Framework 3.0 today, it is still based on the CLR that shipped in .NET Framework 2.0.

    Hope that clarifies the questio.

    Faisal Mohamood

  4. lextm says:

    I think this feature is similar to NAnt’s -targetframework parameter, which will be very useful. Sad that we cannot use such a feature to build against .NET 1.1 using MSBuild now.

  5. Harris says:


    Thanks for your reply; I hadn’t seen any news regarding the target runtime for fx v3.5.

    Thanks again,


  6. Lio380 says:


    I have the …Microsoft.NETFramework64v3.0 and …Microsoft.NETFrameworkv3.0. How I can say to MSBuild to use one or the other? It’s for eliminate the warnings CS1607.


  7. CoqBlog says:

    Jusqu’ici une règle assez simple régissait l’utilisation de Visual Studio : à chaque Framework son Visual

  8. PRASAD says:

    I installed VS 2005 and then went to microsoft update website, which installed framework 3.

    but i am unable to create new project or open VS 2005 projects created on another machine.

    it looks like the  $(MSBuildBinPath) is getting set to a wrong path: C:WINDOWSMicrosoft.NETFrameworkURTInstallPath

    instead of "C:WINDOWSMicrosoft.NETFrameworkv2.0.50727"

  9. Bern McCarty says:

    How do custom MSBuild host programs bind to MSBuild 3.5? What is involved?  

  10. Over the last week or so our team has been planning what we will be working on over the next 12 months.

  11. Greetings MSBuilders! In Visual Studio 2005 you could only target the 2.0 Framework tools. MSBuild targets

  12. As I mentioned the other day, beta2 is coming soon …VS2008 is the first version of VS that will be

  13. chuck123q says:

    In 2.0 this worked in 3.5 it doesn’t, because their is no aspnet_regiis in the 3.5 directory. How could you reliably get encryption to work based on the ToolsVersion="some future or past number"

    <Target Name="AfterBuild">

    <Exec WorkingDirectory="$(OutputPath)" Command="$(MSBuildToolsPath)aspnet_regiis.exe -pef connectionStrings $(OutputPath) -prov HrCustomProvider" />

    <RemoveDir Directories="$(OutputPath)/ConfigFiles" />


  14. [Nacsa Sándor, 2009. január 20. – február 12.] Komplett fejlesztő környezet Windows kliens és web alkalmazások

  15. Laxmi says:

    We want to do multi-targetting, not to different versions, but to different frameworks.  Like, .NET FX, .NET CF, Core CLR …etc.  How can we do that?