错误:无法从 .NET Framework 控制台应用程序使用的 .NET 标准库加载文件或程序集“Microsoft.Win32Registry”

Tyl*_*sen 7 .net c# .net-framework-version .net-assembly .net-standard

问题

Microsoft.Win32.Registry nuget 包给我带来了很多问题。我们有 .NET Framework 4.7.2 库,其中有一个使用该包的帮助程序类,并且在 .NET Framework 4.7.2 单元测试项目中运行良好。我们最近将该库转换为目标 .NET Standard 2.0,现在该类在使用时会出现以下错误:

错误:System.IO.FileNotFoundException:无法加载文件或程序集“Microsoft.Win32.Registry,Version=4.1.1.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a”或其依赖项之一。该系统找不到指定的文件。文件名:“Microsoft.Win32.Registry,Version=4.1.1.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a”位于 NetStandardRegistryLib.RegistryUtil..ctor(String remoteMachineName) at NetStandardRegistryLib.Program.Main(String[] args),位于 C: \src\Microsoft.Win32.Registry-IssueRepro\FrameworkRegistry\RegistryEditor\Program.cs:第 21 行

当我查看控制台项目的输出时,我Microsoft.Win32.Registry.dll在输出中没有看到 。

使用ILSpy并加载我的 .exe - 它似乎会尝试从我的 dotnet core 安装中解析 .dll,但由于它是 .NET Framework 应用程序,因此无法正常工作。

重现

我创建了一个可以在我的 Windows 2010 计算机上重现的存储库。您可以在这里找到它:https ://github.com/TylerNielsen/Microsoft.Win32.Registry-IssueRepro

克隆存储库,然后打开并构建RegistryEditor项目。

使用 Powershell 或您喜欢的编辑器 - 使用三个必需参数调用该工具 [remoteMachineName] [要设置的环境变量名称] [要在环境变量上设置的值] **

** 注意,这实际上需要一台可以通过 IP 地址引用的远程计算机。由于某种原因,使用 127.0.0.1 对我不起作用,但我不确定为什么。该实用程序的用例是访问远程计算机环境变量。

其他注意事项

当我创建用于单元测试的 .NET Framework 类库并引用相同的 .NET 标准库时,该Microsoft.Win32.Registry包已包含在内,并且该实用程序运行良好。

Mic*_*nko 4

在您的存储库中,如果您查看这两个 csproj 文件,您会发现它们非常不同。NetStandardRegistryLib.csproj 是新格式,RegistryEditor.csproj 是旧格式。

您的问题是旧式项目无法传递地解决依赖关系。RegistryEditor 不会复制其自身依赖项 NetStandardRegistryLib 的依赖项。

至少有两种方法可以解决您的问题:

  1. 只需将 Microsoft.Win32.Registry Nuget 包显式添加到RegistryEditor 项目即可。这将使 Microsoft.Win32.Registry.dll 显示在RegistryEditor 构建文件夹中。

  2. 将RegistryEditor.csproj 转换为新格式。它不仅限于 netstandard 构建,您也可以将其用于针对 .Net Framework 版本的构建。它确实可以传递地解决依赖关系!

这是关于如何进行一般转换的长指南https://natemcmaster.com/blog/2017/03/09/vs2015-to-vs2017-upgrade/

由于您的项目非常简单,我已经为您转换了它。只需将RegistryEditor.csproj 的内容替换为以下代码即可。还是瞄准了net472

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net472</TargetFramework>
    <AssemblyName>RegistryEditor</AssemblyName>
    <RootNamespace>RegistryEditor</RootNamespace>
  </PropertyGroup>

  <ItemGroup>
    <ProjectReference Include="..\NetStandardRegistryLib\NetStandardRegistryLib.csproj" />
  </ItemGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)

请注意,以前位于 AssemblyInfo.cs 文件中的几个属性现在由 csproj 文件属性提供,因此您需要从 AssemblyInfo.cs 中删除它们以修复编译错误:

[assembly: AssemblyTitle("RegistryEditor")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("RegistryEditor")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
Run Code Online (Sandbox Code Playgroud)