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

Rab*_*ter 18 c# visual-studio redis nuget servicestack

我使用 C# 创建了一个 Visual Studio(社区 2019)项目,使用ServiceStack.Redis. 由于它是 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;
}
Run Code Online (Sandbox Code Playgroud)

在尝试连接到 Redis 时return facts[sid];,出现异常:

System.IO.FileLoadException:“无法加载文件或程序集“System.Runtime.CompilerServices.Unsafe,Version=4.0.4.1,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a”或其依赖项之一。找到的程序集的清单定义不匹配程序集参考。(来自 HRESULT 的异常:0x80131040)”

(可能是我翻译的不准确)

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

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

Mr *_*ian 24

无法加载文件或程序集 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
    
    Run Code Online (Sandbox Code Playgroud)

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> 
Run Code Online (Sandbox Code Playgroud)

此外,如果您将System.Runtime.CompilerServices.Unsafenuget 包版本更新为较新版本,则还应更改 bindingRedirect 程序集版本。

你可以参考这些汇编版本 System.Runtime.CompilerServices.Unsafe

4.5.xSystem.Runtime.CompilerServices.Unsafenuget 包版本,4.0.x.x而是System.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
Run Code Online (Sandbox Code Playgroud)

  • 要自行查找版本,请转到“C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools”,其中 v10.0A 可能是不同的数字,因此请先检查。在那里你会找到 ildasm.exe。启动它并打开您想要检查版本的 dll。 (4认同)
  • 4.7.0是4.0.6.0,你在哪里找到这个映射?你是不是一一下载下来,用dnSpy之类的工具检查的? (2认同)
  • 如何找到汇编版本? (2认同)

小智 16

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


dat*_*ung 13

根据Perry的回答,我只是安装了nuget包System.Runtime.CompilerServices.Unsafe版本4.5.3,问题就解决了。


DLe*_*Leh 11

就我而言,我在解决方案中安装了最新的 6.0.0.0 软件包(包括 net 472 Web 应用程序!),然后添加了到版本 6 的绑定重定向


      <dependentAssembly>
        <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0"/>
      </dependentAssembly>
Run Code Online (Sandbox Code Playgroud)


tha*_*guy 10

我假设您使用的是 .NET Framework。这个错误是众所周知的,ServiceStack.Redis在 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>
Run Code Online (Sandbox Code Playgroud)

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

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

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


Dav*_*Caz 10

我的应用程序是一个本机 EXE,它加载 .NET 程序集;我们没有 app.config 文件。程序集配置文件不会在运行时加载和使用。因此,我解决此问题所采取的方法是基于此处此处的有用答案。

这个想法是捕获程序集加载异常并通过替换System.Runtime.CompilerServices.Unsafe已加载的任何现有(更高版本)程序集来处理它。

在应用程序启动初期将其添加到某个位置:

AppDomain.CurrentDomain.AssemblyResolve += 
    new ResolveEventHandler(CurrentDomain_AssemblyResolve);
Run Code Online (Sandbox Code Playgroud)

这是事件处理程序:

Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    var name = new AssemblyName(args.Name);
    if (name.Name == "System.Runtime.CompilerServices.Unsafe")
    {
        return typeof(System.Runtime.CompilerServices.Unsafe).Assembly;
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

这在我的情况下非常有效。我也碰巧认为这比(IMO)中潜在的神秘设置更容易发现,app.config所以总的来说它可能是一个很好的解决方案。