gpt4 book ai didi

c# - 为什么我的 .NET 框架应用程序会寻找错误版本的 .NET 核心/标准平台扩展程序集,我该如何解决?

转载 作者:行者123 更新时间:2023-12-04 11:13:20 28 4
gpt4 key购买 nike

来自 the .NET APIs catalog ,据我所知Microsoft.Win32.Registry类在 .NET Standard + Platform Extensions 2.0 中声明组件中的封装 Microsoft.Win32.Registry, Version=4.1.1.0, PublicKeyToken=b03f5f7f11d50a3a .

enter image description here

我创建了一个面向 .NET Standard 2.0 的类库,这是一个简单的类:

public class NetStandardClass
{
public string GetHklmRegValue()
{
var lmKey = Microsoft.Win32.Registry.LocalMachine;
var softwareKey = lmKey.OpenSubKey("Software");
return "value";
}
}

我创建了一个 .NET Framework 4.7.2 控制台应用程序,它引用了我上面的类库:
class Program
{
static void Main(string[] args)
{
string value = new ClassLibrary2.NetStandardClass().GetHklmRegValue();
}
}

当我在 Windows 上运行它时,这会引发一个运行时异常:

System.IO.FileNotFoundException: 'Could not load file or assembly 'Microsoft.Win32.Registry, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.'



基于 what I've read ,在这种情况下出现程序集加载问题在某种程度上是一个已知问题。规定的解决方法是启用 automatic binding redirects并确保我的 .NET Framework 应用程序正在使用 PackageReference而不是 Project.Config .我已经在我共享上述代码的项目中做到了这一点,但我仍然收到错误消息。然而,最让我困惑的是错误指示 .NET Core/ .NET Core + Platform Extensions程序集( 版本=4.1.3.0,PublicKeyToken=b03f5f7f11d50a3a ),而不是 .NET 标准( 版本=4.1.1.0,PublicKeyToken=b03f5904a5|NET 6516510404a5框架 |NET 标准) =4.0.0.0, PublicKeyToken=b77a5c561934e089 ) 来自 API 目录的版本:

enter image description here

输出目录中的 Microsoft.Win32.Registry.DLL 进一步证实了这一点:

enter image description here

基于 further reading ,我可以通过执行以下任一操作来取得一些进展:
  • 添加 <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>到 .NET Standard 类库项目文件

  • - 或者 -
  • 添加 Microsoft.Win32.Registry NuGet 直接打包到我的 .NET Framework 控制台应用程序。

  • 这些都会导致加载某个版本的程序集,但随后我得到了一些奇怪的行为:我得到了 LocalMachine 的 NRE属性(property),这不应该发生。

    enter image description here

    所以这里是问题:

    1.) 既然我的项目是.NET Framework 应用程序,为什么不使用 Microsoft.Win32.Registry .NET Framework API 中的类,特别是 mscorlib同一 API 目录所指的程序集?

    enter image description here

    2.) 为什么 GitHub 帖子中的“解决方法”对我不起作用?

    3.) 为什么它似乎在寻找程序集的 .NET Core/... 扩展版本?

    4.) 为什么当我显式导出 NuGet Microsoft.Win32.Registry .NET Standard 类库中的程序集或直接引用 .NET Framework 控制台应用程序中的包是否会导致奇怪的行为,其中 Microsoft.Win32.Registry.LocalMachine为空,在 Windows 机器上绝不应该是这种情况?

    最佳答案

    以下答案假设安装了最新版本的 Visual Studio 2019(撰写本文时为 v16.4.3),因为这可能会对结果产生一些影响。

    问题 1):

    1.) Since my project is a .NET Framework application, why is it not using the Microsoft.Win32.Registry class in the .NET Framework API, specifically the mscorlib assembly that the same APIs catalog refers to?



    当以以下任一方式设置项目时,这实际上将使用 v4.0.0.0 mscorlib Registry 类:
  • 选项 1
  • 类库:目标框架 = netstandard2.0,NuGet 包 = Microsoft.Windows.Registry (v4.5.0)
  • 控制台应用程序:目标框架 = net472,NuGet 设置为“packages.config”模式,NuGet 包 = Microsoft.Windows.Registry (v4.5.0) [还有 AccessControls 和 Principal.Windows,因为它们是依赖项]
  • 注意:在这里,如果您不添加 Microsoft.Windows.Registry 包,您通常会在查找 4.1.1.0 版 Registry dll 时遇到运行时错误。但我相信它查找的版本基于您安装的当前 .NET Core SDK 版本。
  • 选项 2 [我认为这是你真正想要的]
  • 类库:目标框架 = netstandard2.0,NuGet 包 = Microsoft.Windows.Registry (v4.5.0)
  • 控制台应用程序:目标框架 = net472,NuGet 设置为“PackageReference”模式,NuGet 包 = 无
  • 注意:在 VS2019 中,如果您选中了“首次安装包时允许格式选择”选项,那么它将允许您选择使用 PackageReference 样式,其中 NuGet 包在项目文件中被引用而不是 packages.config .通常,您必须安装任何一个 NuGet 包才能设置此模式,但之后可以卸载该包并保持该模式。我相信您也可以在首次创建 net472 项目之前设置默认模式。
  • 注意:在这里,PackageReference 模式似乎有助于解决对其他 .NET Standard 2.0 类库的 NuGet 依赖关系,而 package.config 模式似乎要求您自己完成。

  • 这应该很容易重现,但是,可能导致某种问题的事情可能是:
    - 正在使用旧版本的 VS2019
    - 在 VS 中为 NuGet 开启跳过绑定(bind)重定向设置
    - .NET 4.7.2 项目的自动绑定(bind)重定向关闭
    - 在包或引用更改后不“重建”解决方案
    - 安装/更新 .NET SDK 或 VS2019 更新后不重新启动计算机
    - 仍然有一个 packages.config 文件

    我还想指出,在上面的 Option 1 中,我在测试中发现,如果您不添加 Microsoft.Windows.Registry 包,它会在运行时查找注册表 dll 的 4.1.1.0 版失败.但是,通过首先安装 Microsoft.Windows.Registry 4.7.0,我能够让它无法查找运行时 4.1.3.0,然后我卸载了它(从而留下了两个依赖包 AccessControl 和 Principal.Windows),并且 没有 重建项目:如果我运行它,它会在运行时失败,它正在寻找 4.1.3.0 版本。重建它会恢复到 4.1.1.0。即使我删除了两个依赖包,这也保持不变。注意:如果您只是删除对项目中 dll 的引用,而不是卸载 NuGet 包,这也适用。

    问题2):

    2.) Why isn't the "work around" in the GitHub post not working for me?



    我有一种感觉,这是因为您的 VS2019 版本可能比 16.4.3 旧。我发现在使用老版本的时候,PackageReference模式还是会导致运行时错误。当我将 VS2019 更新到 16.4.3 时(抱歉,我不确定哪个确切的修订版实际上修复了它),这似乎现在可以正常工作了。我不确定这是否是与各种 SDK 的某种意外交互(也许有些是最近发布的,但不受较旧版本的 VS 支持)。如果packages.config 文件仍然存在,这也可能是一个问题。

    另一个问题可能是受到其他可能已安装且具有不同库版本要求的 NuGet 包的干扰。

    问题 3):

    3.) Why is it seemingly looking for the .NET Core / ... extensions version of the assembly?



    在引用 .NET Standard 2.0(.NET 标准项目默认为 .NET Core 项目)的 .NET 4.7.2 项目中,它将使用 .NET Core 框架,而不是 .NET 框架。因此,默认情况下不提供对注册表的任何引用。您需要 Microsoft.Windows.Registry 包(至少)以允许使用注册表,我相信它可以作为库的 .NET 4.7.2 mscorlib 版本的垫片(如果可用),但使用4.1.1.0 版本作为后备(或 4.1.3.0 版本,如果您从 .NET Core 项目引用)。

    问题 4):

    4.) Why when I explicitly export the NuGet Microsoft.Win32.Registry assembly in the .NET Standard class library or directly reference the package in the .NET Framework console application does it result in the strange behavior where Microsoft.Win32.Registry.LocalMachine is null, which should never be the case on a Windows machine?



    我没有亲自测试过这个,当我测试上述内容时也没有遇到这个问题,但我的感觉是 dll 可能缺少它们依赖的 dll。但进一步考虑,如果是这种情况,可能只会导致另一个运行时错误。我认为问题在于它们不打算直接导出,并且在此过程中可能会丢失一些东西。

    我还要注意的是,如果您在 Windows 以外的任何平台上运行它,注册表可能会返回为 null,因为我认为它不会存在于,例如,Linux 运行时。

    其他注意事项:

    我有一个普遍的感觉,VS 和 .NET Core 通常引用/来自 .NET Framework,这种事情有点问题,并且正在定期取得进展以改进这一点。

    我还发现我遇到了一些我没有预料到的令人惊讶的问题。例如,创建 .NET Standard 控制台应用程序,引用 .NET Standard 类库,但仍然出现运行时错误,无论我在控制台应用程序上安装什么包。您会认为完全相同的目标框架无需任何特殊配置即可工作,但似乎并非如此。但是,如果您改为创建 .NET Core 控制台应用程序,它确实可以正常工作。这有点神秘,但总有一个技术解释在混合中。

    关于c# - 为什么我的 .NET 框架应用程序会寻找错误版本的 .NET 核心/标准平台扩展程序集,我该如何解决?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59742297/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com