【问题标题】:Why VS2012 project with referenced assembly can't target 4.0 automatically为什么带有引用程序集的 VS2012 项目不能自动定位到 4.0
【发布时间】:2013-03-12 14:21:16
【问题描述】:

在 Visual Studio 2012 C# 控制台应用程序中,我将“.NET Framework Target”从 4.5 降级到 4.0。安装了两个框架的 Win 7 Pro。

然后我引用一个程序集,它通过警告抱怨以下内容:

The primary reference "System.Threading.Tasks.Dataflow, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" could not be resolved because it has an indirect dependency on the framework assembly "System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" which could not be resolved in the currently targeted framework. ".NETFramework,Version=v4.0". To resolve this problem, either remove the reference "System.Threading.Tasks.Dataflow, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" or retarget your application to a framework version which contains "System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".

如果我此时尝试编译,则会出错,因为引用程序集的类型和命名空间不可用,就好像根本没有引用程序集一样。

“添加引用”对话框没有任何 System.Runtime 选项,但如果我手动选择 C:\Windows\Microsoft.NET\Framework\v4.0.30319\ 并引用在那里找到的 System.Runtime 程序集,警告消失了,我可以编译了。

问题:

  1. 这样强制 System.Runtime 版本是否会成为未来的潜在问题(部署)。

  2. 如果 VS 项目属性设置为以 Framework 4.0 为目标(这与以 4.0 SystemRuntime/CLR 为目标无关),为什么引用的 DLL 不选择它以及为什么手动添加对我的项目的引用解决了这个问题?

【问题讨论】:

    标签: reference visual-studio-2012 target-framework


    【解决方案1】:

    即使库 System.Runtime 位于 C:\Windows\Microsoft.NET\Framework\v4.0.30319\ 目录中,它也不是 .NET 4.0 框架的一部分。 .NET 4.5 是 4.0 的就地更新,安装在具有相同版本号的同一文件夹中。

    这是一个截图,证明该库在 play .NET 4.0 安装中不存在:

    您还可以通过浏览C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework 目录来验证这一点,您可以在该目录中找到所有已安装框架版本的原始程序集。您会在 .NETCore\v4.5.NETPortable\v4.5 子目录中找到 System.Runtime.dll

    您可以将库添加到项目的原因是运行时在 4.0 和 4.5 之间没有更改,因此 Visual Studio 不知道甚至不关心您手动添加的库是由 4.5 安装的。在这种情况下,Visual Studio 中的定位只是一个过滤器,可避免您不小心将 4.5 程序集添加到以 4.0 为目标的项目中。

    其他信息:

    Rick Strahl 有一篇关于该主题的非常好的博客文章,其中进行了更详细的分析:

    http://www.west-wind.com/weblog/posts/2012/Mar/13/NET-45-is-an-inplace-replacement-for-NET-40

    【讨论】:

    • 我试图理解这一点的含义——它是否真的是说如果一个人在安装了 4.5 的系统上构建,就不能准确地定位 .net 运行时的 4.0 版本?这是否真的意味着为 Windows 2008 服务器编写代码的唯一方法是将我的开发机器降级(咳咳,可能从 Win 8 升级)到 Windows 7 和 VS2010?
    【解决方案2】:

    System.Runtime 版本的这种强制是否是一个潜在问题

    是的,这行不通。它可以在您的机器上运行,因为您安装了 4.5。您的程序将在只有 4.0.0 的客户端计算机上崩溃并烧毁。 从不从 Framework 目录添加引用。很遗憾他们还在,他们得到too many programmers in trouble,但向后兼容是神圣的。

    构建系统只能告诉您在使用参考程序集时遇到了问题。添加引用对话框中显示的那些,它们存储在 c:\program files\reference 程序集中,并且与运行时程序集相同。你知道这行得通,你确实得到了警告。其中,以一种有点笨拙的方式告诉您,您的程序将无法在具有 4.0.0 的机器上运行。不要忽略该警告,您确实必须以 4.5 为目标才能使用该程序集。您无法避免的硬性要求。

    为什么引用的 DLL 没有选择它

    因为它拒绝构建无法运行的程序。功能,而不是错误。

    【讨论】:

    • 该程序在构建后将不知道它是用于 netfx 4 还是 4.5,因为它们都是 CLR4 并且这是唯一以 DLL 为人所知的东西。因此,如果您在 VS 中选择“v4.5”作为目标框架并“合法”引用此 DLL,您仍然会遇到同样的问题 — 必须检查安装程序/入口点中是否存在 4.5。
    • CLR 知道,它会检查编译器自动嵌入的程序集中的 [TargetFramework] 属性。自动为用户提供一个对话框,让他安装正确版本的 .NET。
    • 您确定这不是.exe.config 文件的影响,如果您的NetFX 和Windows 版本足够新,它实际上会触发这种行为? (因此在上面的评论中“签入入口点”)。根据我的经验,如果将 DLL 加载到某个已经运行的 CLR4 应用程序中,则不会发生这样的用户对话框。它会尽可能长时间地运行,它会为缺少的程序集/类型/成员抛出异常,只是常规方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-17
    相关资源
    最近更新 更多