Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change the application target framework when changing build configurations in Visual Studio

I have these build configurations:

enter image description here

These platform configurations:

enter image description here

And these compiler conditionals:

NET40
NET45

My solution is a huge API that consists in 20 solutions, some of those solutions consumes Async keywords and other beneffits that are available only from .NetFx 4.5.

That part of the code I have it in a conditional in this way:

#If NET45 then

    Sub Async
    ...
    End Sub

#Else

    Sub
    ...
    End Sub

#End If

Then, what I'm trying to do is clear, the .NetFx 4.5 build configurations should compile the block of the NET45 conditional, and the .NetFx 4.0 build configurations should compile the block of the #Else part.

The problem I found is that if I change the application target framework in the project settings, the change persist in all the other build configurations, and I would like to avoid that persistance.

So how I can do this?.


Note:

I marked this question with the C# tag because is a general Visual Studio environment question, but I will clarify that my solutions are written in Vb.Net, because I know there are some big differences between the C# project settings and also their compiler params so maybe a C# advanced answer could not help me.

like image 712
ElektroStudios Avatar asked Oct 18 '22 18:10

ElektroStudios


2 Answers

My suggestion is to get rid of conditional statements in code by moving platform/target/etc sencitive code in partial files. Then I would go to project file and would make the icluded files sensitive on particular condition using all the fuctionality ms-build provides

Example:

  • Create brand new VB Console App in Visual Studio
  • add three class files ClassDotNetFeatures40.vb, ClassDotNetFeatures45.vb, GenericClass.vb
  • Add the following code

in GenericClass.vb

Partial Public Class GenericClass
    Public Sub Hello()
        Console.Write("Hello ")
    End Sub
End Class

in ClassDotNetFeatures40.vb

Partial Public Class GenericClass
    Public Sub Word()
        Console.Write("4.0 Word!")
    End Sub
End Class

in

ClassDotNetFeatures45.vb

Public Class GenericClass
    Public Sub Word()
        Console.Write("4.5 Word!")
    End Sub
End Class
  • Put the following code in Module1.vb

    Sub Main()
        Dim o = New GenericClass()
    
        o.Hello()
        o.Word()
    End Sub
    
  • Save all

  • Right click on your solution and press Unload Project
  • Right click on the project file and press Edit Project
  • Find the following lines:
<Compile Include="ClassDotNetFeatures40.vb" />
<Compile Include="ClassDotNetFeatures45.vb" />

and replace them with

<Compile Condition="'$(Configuration)' == 'Debug'" Include="ClassDotNetFeatures40.vb" />
<Compile Condition="'$(Configuration)' == 'Release'" Include="ClassDotNetFeatures45.vb" />
  • press save
  • right click on project file and press Reload

now when you run the project undo debug you will get:

Hello 4.0 Word!

undo release you willl get:

Hello 4.5 Word!

like image 76
Yaugen Vlasau Avatar answered Oct 22 '22 10:10

Yaugen Vlasau


You will need to change project files manually (I've played with csproj - hopefully vbproj works in the same way).

All project configurations properties described in the sections like this one:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
  ...
</PropertyGroup>

Please notice Condition statement - that describes that this particular property set specified for Debug, AnyCPU configuration.

What you need to do is to move TargetFrameworkVersion property from general top level to configuration-specific levels, something like this:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
  <!-- general properties here - removing framework related... -->
  <!--<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>-->
</PropertyGroup>


<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
  <!-- Use 4.0 for Debug -->
  <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>

  <!-- other properties here... -->
</PropertyGroup>


<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
  <!-- Use 4.5 for Release -->
  <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>

  <!-- other properties here... -->
</PropertyGroup>

Please notice that VS.Net GUI does NOT support this, and will not display correct values in the project Properties window; though it will use these values for build.

Depending on complexity of your solution, you might found some other artifacts, as VS.Net will not reload project properly, but at least that should work with build from console.

Additionally, you might need to use similar conditional "hacks" to reference correct libraries.

like image 42
Lanorkin Avatar answered Oct 22 '22 10:10

Lanorkin