无法加载文件或程序集 System.Runtime.CompilerServices.Unsafe

Could not load file or assembly System.Runtime.CompilerServices.Unsafe

我使用 ServiceStack.Redis 使用 C# 创建了一个 Visual Studio(社区 2019)项目。由于它是 C#,我使用 Windows 10(Windows 有一个 Redis 版本,但它真的很旧,据我所知,它不是官方的,所以我担心这可能是问题所在)。 这是我的代码的摘录:

public class PeopleStorage: IDisposable
{
    public PeopleStorage()
    {
        redisManager = new RedisManagerPool("localhost");
        redis = (RedisClient)redisManager.GetClient();
        facts = (RedisTypedClient<List<Fact>>)redis.As<List<Fact>>();
    }

    public List<Fact> GetFacts(int id)
    {
        string sid = id.ToString();
        if (facts.ContainsKey(sid))
            return facts[sid];
        return accessor.GetFacts(id);
    }

    private RedisTypedClient<List<Fact>> facts;
    private RedisClient redis;
    private RedisManagerPool redisManager;
}

在行 return facts[sid]; 中尝试连接到 Redis 时发生异常:

System.IO.FileLoadException: "Could not load file or assembly "System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" or one of it's dependences. The found Assembly's manifest definition does not match the Assembly reference. (Exception from HRESULT: 0x80131040)"

(我翻译的可能不准确)

我尝试更新所有包,从 ServiceStack 包开始,到 System.Runtime.CompilerServices.Unsafe 本身结束。而且NuGet中不能选择4.0.4.1版本,最接近的是4.0.0,相关的是4.0.7。

我不明白为什么它使用这个版本以及如何解决这个问题。
即使完全重新安装 Visual Studio 也无济于事。

我假设您使用的是 .NET Framework。此错误已知为 ServiceStack.Redis 并且是 tracked on GitHub。发生这种情况是因为您使用的库依赖于 System.Runtime.CompilerServices.Unsafe 不同版本 。需要解决和合并这些传递依赖关系,以在输出文件夹中形成一个程序集。您最终将获得这些版本中的最新版本。因此,如果其中一个库依赖于较旧的特定版本,将找不到它。

导致此问题的错误已在 System.Runtime.CompilerServices.Unsafe 4.6.0 中修复。使用 binding redirects,加载您需要的特定版本的程序集。将此代码段插入您的所有 app.config 个文件。

<dependentAssembly>
    <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" />
</dependentAssembly>

您需要将所需程序集的 assembly 版本指定为 newVersion。这与您在安装 NuGet 包时选择的 package 版本不同。他们是这样对应的:

  • Package 4.5.3 包含程序集版本为 4.0.4.1
  • 程序包 4.7.0 包含程序集版本 4.0.6.0

在此绑定重定向中,我使用了修复错误的较新版本 System.Runtime.CompilerServices.Unsafe。但是,如果您依赖旧版本,请使用 4.0.4.1.

Could not load file or assembly System.Runtime.CompilerServices.Unsafe

看来你已经安装了 System.Runtime.CompilerServices.Unsafe nuget 包 4.5.3 版本。并且对应System.Runtime.CompilerServices.Unsafe.dll汇编版本4.0.4.1.

建议

1) 请尝试将 System.Runtime.CompilerServices.Unsafe 版本 4.0.4.1 注册到 GAC 以便系统可以。

  • 运行 VS2019 的开发人员命令提示符 作为 管理员

  • 类型:

    cd xxxxx (the path of the the System.Runtime.CompilerServices.Unsafe 4.0.4.1)
    
    gacutil /i System.Runtime.CompilerServices.Unsafe.dll
    

2) 如果您使用带有 xxx.config 文件的 Net Framework 项目,您可以使用 bindingRedirect.

将这些添加到 app.config 文件或 web.config 文件中:

<configuration>  
   <runtime>  
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">  
         <dependentAssembly>  
            <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe"  
                              publicKeyToken="b03f5f7f11d50a3a"  
                              culture="neutral" />  
            <bindingRedirect oldVersion="0.0.0.0-4.0.4.1"  
                             newVersion="4.0.4.1"/>  
         </dependentAssembly>  
      </assemblyBinding>  
   </runtime>  
</configuration> 

除此之外,如果你更新System.Runtime.CompilerServices.Unsafe nuget包版本到较新的版本,你也应该改变bindingRedirect程序集版本。

可以参考System.Runtime.CompilerServices.Unsafe

这些汇编版本

4.5.xSystem.Runtime.CompilerServices.Unsafe nuget 包版本,而 4.0.x.xSystem.Runtime.CompilerServices.Unsafe.dll 程序集版本。

4.5.0 is 4.0.4.0 
4.5.1 is 4.0.4.0 
4.5.2 is 4.0.4.0 
4.5.3 is 4.0.4.1
4.6.0 is 4.0.5.0
4.7.0 is 4.0.6.0
4.7.1 is 4.0.6.1
5.0.0 is 5.0.0.0

根据我的经验,我不需要安装 System.Runtime.CompilerServices.Unsafe 因为它是从另一个包 npgsql 引用的。 相反,我所做的如下:

  1. 将此代码片段插入到项目app.config
 <configuration>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
          <dependentAssembly>
            <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="4.1.4.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral"/>
            <bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1"/>
          </dependentAssembly>
        </assemblyBinding>
      </runtime>
    </configuration>
  1. 运行再次项目

这是我目前找到的解决方案,添加 dependentAssembly bindingReference

根据Perry的回答,简单安装了nuget包System.Runtime.CompilerServices.Unsafe版本4.5.3,问题解决.

最近我遇到了完全相同的错误信息。但是,该消息并未出现在我用来测试我的应用程序的所有 PC 中。一些 PC 产生了错误消息,而另一些则没有。我无法区分哪些是 PC 的特征会生成错误消息,哪些不会。似乎..随机.

然后我在编译我的应用程序时注意到一条警告消息(我当时使用的是 Visual Studio 2019):

Severity Code Description Project File Line Suppression State Warning Found conflicts between different versions of the same dependent assembly. Please set the "AutoGenerateBindingRedirects" property to true in the project file. For more information, see http://go.microsoft.com/fwlink/?LinkId=294190. SQL Online Exam System

我完全按照它告诉我的去做了:

然后问题就解决了

我的问题已通过删除“bin”和“obj”文件夹得到解决。

根据我糟糕的经历:我正在将项目添加到解决方案中,该解决方案已经有“System.Runtime.CompilerServices.Unsafe”版本=“4.5.0” 当我开始使用 Microsoft.Toolkit.Mvvm NuGet 时,它会尝试检索“System.Runtime.CompilerServices.Unsafe”> 5.0.0 以及其他 DLL。它让地狱。所以,我搬到了 MVVM Cross,我很高兴。

感谢@thatguy 终于解决了问题。

对我有用的解决方案来自 Nick Craver,详细信息如下:

Things to try:

** Reference the System.Runtime.CompilerServices.Unsafe library directly as a (so VS alerts it needs a binding and offers a one-click fix...sometimes it won't realize this transitively).

** If using app.config, remove all binding redirects and add a true property up on the top.


This is a load errors and I really really really wish they had a wiki page explaining how to fix this because it can plague any library anyway if you step on one of the magical landmines.