在 Visual Studio 中更改构建配置时更改应用程序目标框架

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

我有这些构建配置:

这些平台配置:

这些编译器条件:

NET40
NET45

我的解决方案是一个巨大的 API,包含 20 个解决方案,其中一些解决方案使用 Async 关键字和其他仅可从 .NetFx 4.5 获得的好处。

我的那部分代码是这样有条件的:

#If NET45 then

    Sub Async
    ...
    End Sub

#Else

    Sub
    ...
    End Sub

#End If

然后,我想做的很清楚,.NetFx 4.5 构建配置应该编译 NET45 条件块,.NetFx 4.0 构建配置应该编译 #Else部分。

我发现的问题是,如果我在项目设置中更改应用程序目标框架,更改会在所有其他构建配置中持续存在,我想避免这种持续存在。

那我该怎么做呢?


注:

我用 C# 标签标记了这个问题,因为这是一个一般的 Visual Studio 环境问题,但我会澄清我的解决方案是用 Vb.Net 编写的,因为我知道它们之间存在一些很大的差异C# 项目设置及其编译器参数,所以 C# 高级答案可能帮不了我。

我的建议是通过在部分文件中移动 platform/target/etc 敏感代码来摆脱代码中的条件语句。然后我会转到项目文件,并使用 ms-build 提供的所有功能

使包含的文件在特定条件下敏感

示例:

  • 在 Visual Studio
  • 中创建全新的 VB 控制台应用程序
  • 添加三个class个文件ClassDotNetFeatures40.vb、ClassDotNetFeatures45.vb、GenericClass.vb
  • 添加以下代码

在GenericClass.vb

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

在ClassDotNetFeatures40.vb

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

ClassDotNetFeatures45.vb

Public Class GenericClass
    Public Sub Word()
        Console.Write("4.5 Word!")
    End Sub
End Class
  • 将以下代码放入Module1.vb

    Sub Main()
        Dim o = New GenericClass()
    
        o.Hello()
        o.Word()
    End Sub
    
  • 全部保存

  • 右键单击您的解决方案并按 卸载项目
  • 右键单击项目文件并按 编辑项目
  • 找到以下几行:
<Compile Include="ClassDotNetFeatures40.vb" />
<Compile Include="ClassDotNetFeatures45.vb" />

并将它们替换为

<Compile Condition="'$(Configuration)' == 'Debug'" Include="ClassDotNetFeatures40.vb" />
<Compile Condition="'$(Configuration)' == 'Release'" Include="ClassDotNetFeatures45.vb" />
  • 按保存
  • 右键单击项目文件并按 重新加载

现在,当您 运行 项目撤消调试时,您将得到:

Hello 4.0 Word!

撤销释放你会得到:

Hello 4.5 Word!

您将需要手动更改项目文件(我玩过 csproj - 希望 vbproj 以相同的方式工作)。

像这样的部分中描述的所有项目配置属性:

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

请注意 Condition 语句 - 描述了为 Debug, AnyCPU 配置指定的此特定 属性 集。

您需要做的是将 TargetFrameworkVersion 属性 从一般顶级移动到 configuration-specific 级别,如下所示:

<?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>

请注意 VS.Net GUI 不支持此功能,并且不会在项目属性 window 中显示正确的值;虽然它将使用这些值进行构建。

根据您的解决方案的复杂性,您可能会发现一些其他工件,因为 VS.Net 不会正确地重新加载项目,但至少应该适用于从控制台构建。

此外,您可能需要使用类似的条件 "hacks" 来引用正确的库。