使用 Directory.Build.Props 更改 .NetFramework 项目上的 TargetFrameworkVersion 意外影响 .NetStandard 项目
Using Directory.Build.Props to change TargetFrameworkVersion on .NetFramework projects affects .NetStandard projects unexpectedly
我正在尝试使用 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>
Directory.Build.props
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup Condition="'$(TargetFramework.Contains(netstandard))' == 'false'">
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
</PropertyGroup>
</Project>
怎么会错呢?
正如this document所说,Directory.Build.props
是在MSBuild的早期导入的,这意味着它会先执行文件的内容,然后再从xxx.csproj
文件中读取所有属性你的项目。
而Directory.Build.targets
是在xxx.csproj
文件末尾导入的,所以可以覆盖属性。
Directory.Build.props
通常用于创建全局属性,而Directory.Build.targets
用于覆盖属性。
============================================= =============================
对于 Net Framework 项目,
在你的问题中,MSBuild首先读取Directory.Build.props
中的属性TargetFrameworkVersion 4.8
并且这是真的。
属性 TargetFramework
在 net framework
项目中不存在(它是一个 属性 用于新的 sdk 项目 ), 所以值为空, 条件总是flase
所以条件成立.(flase=false
).
然后,MSBuild读取xxx.csproj
,它会读取属性TargetFrameworkVersion 4.6.1
然后覆盖属性4.8
。所以它将始终使用值 4.6.1
.
============================================= =============================
对于 Net Standard 项目,属性 TargetFramework
在 xxx.csproj
文件下定义。而当你第一次阅读内容并在Directory.Build.props
文件中使用它时。
因为文件在读取xxx.csproj
之前运行,所以TargetFramework
属性还没有定义,所以条件是false
。 false=false
引出条件成立。它将读取 属性 TargetFrameworkVersion 4.8
而网络标准项目使用 属性 TargetFramework
.
TargetFrameworkVersion
设置为net framework 4.8
,而在net标准项目中,该值通常为v2.0
或v2.1
(net standard 2.0
或net standard 2.1
), 它无法将 net framework 4.8
读入网络标准项目。而后面的xxx.csproj
文件没有值覆盖TargetFrameworkVersion
为正常的net standard
值
因此 TargetFrameworkVersion
作为 net framework
的值嵌入到 net standard
项目中,因此构建因不兼容而失败。
解决方案
而不是,您应该将 Directory.Build.props
文件重命名为 Directory.Build.targets
.
然后,重新启动您的项目,重建您的解决方案以启用它。而且在我这边也能很好地发挥作用。
注意:尽管您右键单击项目 Properties-->Application-- >Target Framework 显示旧的 net framework 4.6.1
,MSBuild 已将其设置为 net48
。
只是UI显示问题,没关系,可以忽略。
我正在尝试使用 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>
Directory.Build.props
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup Condition="'$(TargetFramework.Contains(netstandard))' == 'false'">
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
</PropertyGroup>
</Project>
怎么会错呢?
正如this document所说,Directory.Build.props
是在MSBuild的早期导入的,这意味着它会先执行文件的内容,然后再从xxx.csproj
文件中读取所有属性你的项目。
而Directory.Build.targets
是在xxx.csproj
文件末尾导入的,所以可以覆盖属性。
Directory.Build.props
通常用于创建全局属性,而Directory.Build.targets
用于覆盖属性。
============================================= =============================
对于 Net Framework 项目,
在你的问题中,MSBuild首先读取Directory.Build.props
中的属性TargetFrameworkVersion 4.8
并且这是真的。
属性 TargetFramework
在 net framework
项目中不存在(它是一个 属性 用于新的 sdk 项目 ), 所以值为空, 条件总是flase
所以条件成立.(flase=false
).
然后,MSBuild读取xxx.csproj
,它会读取属性TargetFrameworkVersion 4.6.1
然后覆盖属性4.8
。所以它将始终使用值 4.6.1
.
============================================= =============================
对于 Net Standard 项目,属性 TargetFramework
在 xxx.csproj
文件下定义。而当你第一次阅读内容并在Directory.Build.props
文件中使用它时。
因为文件在读取xxx.csproj
之前运行,所以TargetFramework
属性还没有定义,所以条件是false
。 false=false
引出条件成立。它将读取 属性 TargetFrameworkVersion 4.8
而网络标准项目使用 属性 TargetFramework
.
TargetFrameworkVersion
设置为net framework 4.8
,而在net标准项目中,该值通常为v2.0
或v2.1
(net standard 2.0
或net standard 2.1
), 它无法将 net framework 4.8
读入网络标准项目。而后面的xxx.csproj
文件没有值覆盖TargetFrameworkVersion
为正常的net standard
值
因此 TargetFrameworkVersion
作为 net framework
的值嵌入到 net standard
项目中,因此构建因不兼容而失败。
解决方案
而不是,您应该将 Directory.Build.props
文件重命名为 Directory.Build.targets
.
然后,重新启动您的项目,重建您的解决方案以启用它。而且在我这边也能很好地发挥作用。
注意:尽管您右键单击项目 Properties-->Application-- >Target Framework 显示旧的 net framework 4.6.1
,MSBuild 已将其设置为 net48
。
只是UI显示问题,没关系,可以忽略。