netstandard2.0 (.net standard 2.0) 类库不能引用 net461 (.net framework 4.6.1) 类库

Posted

技术标签:

【中文标题】netstandard2.0 (.net standard 2.0) 类库不能引用 net461 (.net framework 4.6.1) 类库【英文标题】:netstandard2.0 (.net standard 2.0) class library cannot reference a net461 (.net framework 4.6.1) class library 【发布时间】:2018-10-13 21:00:09 【问题描述】:

如果之前有人问过这个问题,首先抱歉。 netstandard2.0发布后,我搜索了很多信息,有很多矛盾和过时的信息。

我正在学习新的网络标准和核心迁移,并使用 CLI dotnet 命令构建了空的香草“hello world”项目。 有 Nuget 参考。

问题是添加从 netstandard2.0 类库到 net461 类库的引用会导致错误 (netstandard2.0 --> net461 参考)

"cannot be added due to incompatible targeted frameworks between the two projects. Please review the project you are trying to add and verify that is compatible with the following targets"

Rich Lander 的这篇微软文章声称我可以用 netstandard2.0 做到这一点

https://blogs.msdn.microsoft.com/dotnet/2017/06/28/announcing-net-core-2-0-preview-2/#user-content-reference-net-framework-libraries-from-net-standard

Immo Landwerth [MSFT] 在他的文章中似乎暗示了通过兼容性垫片的可能性,我相信这可能只是 Nuget 参考:

https://blogs.msdn.microsoft.com/dotnet/2016/09/26/introducing-net-standard/

(也许 Scott Hanselman 可以帮忙!)

netsandard2.0 似乎支持 net461,“.NET implementation support”网格显示了这一点。

https://docs.microsoft.com/en-us/dotnet/standard/net-standard

示例代码

已经创建了一个 GitHub 存储库来演示这一点

https://github.com/raxuser100/net_standard_references.git https://github.com/raxuser100/net_standard_references/tree/master

克隆上面的 master 并从命令提示符运行它:

dotnet add .\classlib_netstandard2.0_ref_classLib_net461\classlib_netstandard2.0_ref_classLib_net461.csproj reference .\classlib_net461\classlib_net461.csproj

然后你会得到错误。

csproj文件有以下内容 classlib_net461.csproj

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

classlib_netstandard2.0.csproj

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

CLI DotNet 命令脚本

我已使用以下 CLI 命令创建项目结构:

dotnet new console --name console_core2.0 --framework netcoreapp2.0
dotnet new classlib --name classlib_netstandard2.0 --framework netstandard2.0
dotnet new classlib --name classlib_net461 --target-framework-override net461

# netstandard2.0 --> net461 link
dotnet new classlib --name classlib_netstandard2.0_ref_classLib_net461 --framework netstandard2.0

<#
add project a reference 
netstandard2.0 --> net461 link

this returns an error

 cannot be added due to 
incompatible targeted frameworks between the two projects. Please review the project you are trying to add and verify that is compatible with the following targets:
At line:1 char:1


Works if we edit classlib_net461.csproj and add multiple targets including netstandard2.0

 <PropertyGroup>
    <TargetFrameworks>net461;netstandard2.0</TargetFrameworks>
  </PropertyGroup>


#>
dotnet add .\classlib_netstandard2.0_ref_classLib_net461\classlib_netstandard2.0_ref_classLib_net461.csproj reference .\classlib_net461\classlib_net461.csproj

向 classLib_net461 添加多个目标的解决方法

如果我们编辑 classlib_net461.csproj 并添加多个目标(包括 netstandard2.0)就可以工作

classlib_net461.csproj

<PropertyGroup>
    <TargetFrameworks>net461;netstandard2.0</TargetFrameworks>
</PropertyGroup>

现在当我们参考时,它可以正常工作,如下所示:

classlib_netstandard2.0_ref_classLib_net461.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <ItemGroup>
    <ProjectReference Include="..\classlib_net461\classlib_net461.csproj" />
  </ItemGroup>

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>
</Project>

这是否可行,因为现在两个类库都针对 netstandard2.0

问题

有没有一个简单的图表可以用所有的陷阱简单地揭开这一切的神秘面纱!

为什么这不起作用。如果一个空的 netstandard2.0 实现了 net461 的大部分内容,那么它肯定拥有支持裸 net461 引用所需的一切。我知道有一些 api 不起作用,即 WPF,但是这些都是裸项目,没有 Nuget 或直接二进制引用。

解决方法,为什么会这样?我们是否总是需要在 classlib 中同时定位 net461 和 netstandard2.0,以便它们只能被 netstandard2.0 类库引用。

在 netstandard2.0 类库中使用较旧的 .net 框架类库(net4.3 及更高版本)的正确结构是什么。

这是怎么做到的?

https://blogs.msdn.microsoft.com/dotnet/2017/06/28/announcing-net-core-2-0-preview-2/#user-content-reference-net-framework-libraries-from-net-standard

【问题讨论】:

.netstandard 提供了 net461 中可用类的一小部分。可以在不同的操作系统和项目类型上工作的那种。隐含的是您不能添加对 net461 程序集的引用。因为那样构建结果将不再是 netstandard。 有一个 PR 已经解决了这个问题 - 计划用于 MSBuild 15.8,请检查答案中喜欢的 GH 问题。 反过来,他们确保 .netstandard 程序集可以在具有 net461 的机器上运行。还有其他的。 它受支持 (core/netstandard => 网络框架),但它处于受支持的边缘,并且在不兼容的操作系统上会失败,并出现 PlatformNotSupportedException。它会让你发疯,各种警告和绑定重定向、FileNotFoundExceptions、fml 和 System.Net.Http 杀死了我的母亲。 4.7.2如果使用新的csproj格式会好一些,如果升级旧项目文件则完全没有。 【参考方案1】:

对 .NET Standard 2.0+ 和 .NET Core 2.0+ 项目引用 .NET Framework 库的支持目前仅限于 NuGet 包(通过特殊的回退定义),这就是为什么它不适用于您的项目-项目参考。

当 MSBuild 为此使用相同的解决策略时,这可能会在即将发布的工具版本中发生变化。见this tracking GitHub issue。

【讨论】:

非常感谢您的回答。我检查了你提到的 GitHib 问题。老实说,不确定我是否理解。这是否意味着这篇文章是错误的,说项目可以参考? blogs.msdn.microsoft.com/dotnet/2017/06/28/…我想知道 Rich Lander(微软)是如何在他的屏幕截图(预览版)中做到这一点的?我今天确实给他发了推文,也许他可以解释一下。 我相信这是在预览期间,NuGet 从 FrameworkTargetFallback 移动到 AssetTargetFallback。此外,在 2.0 发布后(工具版本 2.1.4+ 左右),解析项目引用的方式(“ProjectReference 协议”)也发生了变化。但是这个问题和已经公开的 PR 明确地是关于(重新?)启用这种情况。 但请注意,该功能的主要目标是在 .NET Core 应用程序中使用现有的 NuGet 包。如果您的代码在您的控制之下,请考虑直接定位 netstandard2.0netcoreapp2.0 并在需要时使用 Microsoft.Windows.Compatibility NuGet 包(目前处于预览状态;带回一些经典 API,其中一些仅在运行时才有效在 Windows 上)。

以上是关于netstandard2.0 (.net standard 2.0) 类库不能引用 net461 (.net framework 4.6.1) 类库的主要内容,如果未能解决你的问题,请参考以下文章

我们从哪里获得 .Net Standard 2.0 中的 System.IdentityModel

为啥 .NET 框架项目可以作为参考添加到 .NET Standard 2.0 项目中?

无法在面向 .Net Standard 2.0 的项目中加载 Revit API

RSACryptoServiceProvider.VerifyData 在 .Net5.0 中始终返回 false

.net 标准兼容性

如何使用多个目标框架测试 .NET 库