首页 > 解决方案 > 使用 Directory.Build.Props 更改 .NetFramework 项目上的 TargetFrameworkVersion 会意外影响 .NetStandard 项目

问题描述

我正在尝试使用 Directory.Build.props 文件将一堆项目的 TargetFrameworkVersion 从 v4.6.1 更改为 v4.8。
我在 Directory.Build.props 文件下有一个 .net 框架和 .net 标准项目的组合,我想在更新时忽略 .net 标准项目。
.net 框架项目的一切都按预期工作但是,条件"'$(TargetFramework.Contains(netstandard))' == 'false'"相反!对于.net 标准的。
换句话说,为这个项目添加了属性并且构建失败,而它不应该。

MyClassLibrary.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>
</Project>

目录.Build.props

<?xml version="1.0" encoding="utf-8"?>
<Project>
    <PropertyGroup Condition="'$(TargetFramework.Contains(netstandard))' == 'false'">
        <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
    </PropertyGroup>
</Project>

怎么可能是错的?

标签: visual-studiomsbuild

解决方案


As this document said, Directory.Build.props is imported very early during MSBuild and it means that it will execute the contents of the file first before reading all the properties from xxx.csproj file in your project.

And Directory.Build.targets is imported at the end of the xxx.csproj file, so it can overwrite properties.

Directory.Build.props usually is used for creating global properties while Directory.Build.targets is used for overwriting properties.

==========================================================================

For Net Framework projects,

In your issue, MSBuild first reads the property TargetFrameworkVersion 4.8 in Directory.Build.props and it is true.

The property TargetFramework does not exist in the net framework projects(it is a property for new sdk project), so the value is empty, and the condition is always flase so that the condition is established.(flase=false).

Then, MSBuild reads the xxx.csproj, it will read property TargetFrameworkVersion 4.6.1 and then overwrite the property 4.8. So it will always use the value 4.6.1.

==========================================================================

For Net Standard projects, the property TargetFramework is defined under xxx.csproj file. And when you first read the content and use it in the Directory.Build.props file.

Because the file runs before reading xxx.csproj, the TargetFramework property has not been defined yet, so the condition is false. false=false leads to the establishment of conditions. It will read the property TargetFrameworkVersion 4.8 while net standard projects uses property TargetFramework.

TargetFrameworkVersion is set to net framework 4.8 while in net standard projects, the value is usually v2.0 or v2.1(net standard 2.0 or net standard 2.1), it cannot read the net framework 4.8 into a net standard project. And the subsequent xxx.csproj file has no value to overwrite TargetFrameworkVersion to the normal net standard value.

So TargetFrameworkVersion is embedded in the net standard project as the value of net framework, so the build fails due to incompatibility.

Solution

Instead, you should rename the Directory.Build.props file to Directory.Build.targets.

Then, restart your project, rebuild your solution to enable it. And it can work well in my side.

Note that: Although you right click project Properties-->Application-->Target Framework shows the old one net framework 4.6.1, the MSBuild already set it to net48.

enter image description here

It is just a UI display issue, it doesn't matter, you can ignore it.


推荐阅读