.net – Target specific version of .NET framework at Visual Studio 2010 Solution level

netvisual studio 2010

I would like to target both .NET 3.5 and .NET 4.0 in my Visual Studio 2010 solution.

I am aware that I can set the <TargetFrameworkVersion /> in my project files, however this requires me to edit every project file before building the solution for a specific .NET framework version. Scott Dorman provides a macro which does the trick on his blog post Visual Studio 2010 and Target Framework Version.

I am looking for a global solution where I don't have to change the setting in every project. Is it possible to change a central setting at the solution level to achieve the same thing?

Best Answer

As Jon Skeet wrote, there is no apparent way to define the target framework at the solution level. However, this can be done by adding specific configurations to the solution, then editing the *.csproj files manually to specify the targets for every configuration, rather than globally for the whole project.

Here is a step-by-step guide:

  1. Select Build - Configuration Manager.
  2. In the Active solution configuration drop-down list, select and enter a meaningful name (e.g. Debug v3.5) based on whatever existing settings you already have.
  3. For each project file, open it in the editor (you can do this in Visual Studio, but you have to first right-click on it in the Solution Explorer and select Unload Project, then Edit xyz.csproj).
  4. Find the <PropertyGroup> element which matches the configuration you have just created (for instance Debug v3.5|AnyCPU).
  5. Add in the XML, for instance after the closing </PlatformTarget> element, the <TargetFrameworkVersion> and <TargetFrameworkProfile> you need.
  6. Save the file.
  7. In the Solution Explorer, use the command Reload Project to make the project available again.

Here is a sample:

<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug v3.5|AnyCPU'">
  <DebugSymbols>true</DebugSymbols>
  <OutputPath>bin\Debug v3.5\</OutputPath>
  <DefineConstants>DEBUG;TRACE;DOTNET35</DefineConstants>
  ...
  <DebugType>full</DebugType>
  <PlatformTarget>x86</PlatformTarget>
  <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
  <TargetFrameworkProfile>Client</TargetFrameworkProfile>
  ...
</PropertyGroup>

Note that I also define the symbol DOTNET35, which allows me to write framework dependent #if statements in the source code. I had, for instance, a few pieces of code which relied on System.Tuple and by adding a minimalistic version of the class, I could back-port my .NET 4.0 application to .NET 3.5.

Here is my snippet:

#if DOTNET35
namespace System
{
    public class Tuple<T1, T2>
    {
        public Tuple(T1 item1, T2 item2)
        {
            this.item1 = item1;
            this.item2 = item2;
        }

        public T1 Item1
        {
            get
            {
                return this.item1;
            }
        }

        public T2 Item2
        {
            get
            {
                return this.item2;
            }
        }

        private readonly T1 item1;
        private readonly T2 item2;
    }
}
#endif