【问题标题】:Change the application target framework when changing build configurations in Visual Studio在 Visual Studio 中更改构建配置时更改应用程序目标框架
【发布时间】:2016-01-08 09:00:37
【问题描述】:

我有这些构建配置:

这些平台配置:

还有这些编译器条件:

NET40
NET45

我的解决方案是一个包含 20 个解决方案的巨大 API,其中一些解决方案使用 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# 高级答案对我没有帮助。

【问题讨论】:

  • 我认为 C# 标签不合适。您已经应用了常规标签。

标签: c# .net vb.net visual-studio msbuild


【解决方案1】:

我的建议是通过在部分文件中移动平台/目标/等敏感代码来摆脱代码中的条件语句。然后我会转到项目文件,并使用 ms-build 提供的所有功能使包含的文件在特定条件下敏感

例子:

  • 在 Visual Studio 中创建全新的 VB 控制台应用程序
  • 添加三个类文件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" />
  • 按保存
  • 右键单击项目文件并按重新加载

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

你好 4.0 字!

撤销释放你会得到:

你好 4.5 字!

【讨论】:

【解决方案2】:

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

所有项目配置属性都在类似这样的部分中描述:

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

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

您需要做的是将TargetFrameworkVersion 属性从一般顶级移动到特定于配置的级别,如下所示:

<?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 不支持这一点,并且不会在项目属性窗口中显示正确的值;虽然它会使用这些值进行构建。

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

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

【讨论】:

  • 感谢您的回答,感谢您的帮助和您花时间分析它,但我不能将其视为解决方案,因为它会产生更多问题,而且这些额外问题将比其他问题更大或更危险我拥有的当前一个,并且它们也应该需要以相同的方式解决,并在项目文件中使用更棘手的手动破解。我对其进行了测试,正如您所提到的,VS 似乎不支持这种黑客攻击,因为一旦应用了这些修改,我就无法更改 UI 中的目标框架。我想知道是否存在一个简单的解决方案。
  • @ElektroStudios 我认为您不会找到简单的解决方案:您希望 GUI 支持在编译期间选择条件框架版本,但 VS 明确表示当您更改项目的目标框架版本时需要重新加载项目;因此,如果存在解决方案,它应该使用已经“正确”的目标框架打开解决方案。作为一个类似的选项,您可以使用两组不同的解决方案 + csproj 文件(而不是配置),一组用于 4.0,另一组用于 4.5,它们将使用相同的源文件 - 但这将导致非常高的支持成本跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-16
相关资源
最近更新 更多