“无法加载文件或程序集'System.Core,版本= 2.0.5.0,...”动态加载可移植类库时的异常 [英] "Could not load file or assembly 'System.Core, Version=2.0.5.0,..." exception when loading Portable Class Library dynamically

查看:477
本文介绍了“无法加载文件或程序集'System.Core,版本= 2.0.5.0,...”动态加载可移植类库时的异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我需要强调的是,这个问题与此线程。此外,安装 KB2468871 无效。

First of all I need to emphasize that this is slightly different question than the one in this thread. Additionally, installing KB2468871 doesn't help.

我试图尽可能简化此问题。通常,它涉及使用Assembly.LoadFile(...)在桌面应用程序中加载PCL程序集。

I tried to simplify this problem as much as possible. In general it about loading PCL assemblies in Desktop application with Assembly.LoadFile(...).

我们假设有一个.NET 4.0控制台应用程序(称为 C )。它引用.NET 4.0程序集(称为 N4)和PCL程序集(称为 PCL)。

Let's say there is a .NET 4.0 Console Application (called "C"). It references .NET 4.0 assembly (called "N4") and PCL assembly (called "PCL").

其中N4如下:

using System.Linq;

namespace N4
{
    public class ClassInN4
    {
        public static string Greet()
        {
            return new string(
                "hello from N4"
                .ToCharArray()
                .Select(char.ToUpper)
                .ToArray()
            );
        }
    }
}

PCL看起来像这样:

PCL looks like this:

using System.Linq;

namespace PCL
{
    public class ClassInPCL
    {
        public static string Greet()
        {
            return new string(
                "hello from pcl"
                .ToCharArray()
                .Select(char.ToUpper)
                .ToArray()
            );
        }
    }
}

和C看起来像这样:

using System;
using System.IO;
using System.Reflection;
using N4;
using PCL;

namespace C
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            Test();
            Console.ReadLine();
        }

        private static void Test()
        {
            Test("N4", ClassInN4.Greet);
            Test("PCL", ClassInPCL.Greet);
        }

        private static void Test(
            string title, 
            Func<string> generator)
        {
            try
            {
                Console.WriteLine(
                    "{0}: {1}", title, generator());
            }
            catch (Exception e)
            {
                Console.WriteLine(
                    "{0}: {1} -> {2}", title, e.GetType(), e.Message);
            }
        }
    }
}

何时您运行此应用程序,您将获得绝对正确的结果:

When you run this application you get absolutely correct results:

N4: HELLO FROM N4
PCL: HELLO FROM PCL

我们将AssemblyResolve事件添加到Program.Main中的CurrentDomain中:

Let's add AssemblyResolve event to CurrentDomain in Program.Main:

AppDomain.CurrentDomain.AssemblyResolve += (_, a) => {
    var fileName = Path.GetFullPath(
        new AssemblyName(a.Name).Name + ".data");
    Console.WriteLine("Probing '{0}'", fileName);
    return 
        File.Exists(fileName) 
        ? Assembly.LoadFile(fileName) 
        : null;
};

因此,如果找不到程序集,它将尝试从 .data文件加载该文件怎么办

So, what it does if assembly cannot be found it tries to load it from ".data" file.

让我们转到应用程序文件夹,将 N4.dll重命名为 N4.data并运行 C.exe。

Let's go application folder and rename "N4.dll" to "N4.data" and run "C.exe".

Probing 'C:\xxx\C\bin\Debug\N4.data'
N4: HELLO FROM N4
PCL: HELLO FROM PCL

因此它经过AssemblyResolve并最终加载 N4.data并以

So it goes through AssemblyResolve and finally loads "N4.data" and works as good as original.

让我们将 N4.data恢复为 N4.dll,并将 PCL.dll重命名为 PCL.data,然后...

Let's revert "N4.data" to "N4.dll" and rename "PCL.dll" to "PCL.data" and...

Probing 'C:\xxx\C\bin\Debug\PCL.data'
N4: HELLO FROM N4
Probing 'C:\xxx\C\bin\Debug\System.Core.data'
Probing 'C:\xxx\C\bin\Debug\System.Core.data'
Probing 'C:\xxx\C\bin\Debug\System.Core.data'
PCL: System.IO.FileNotFoundException -> Could not load file or assembly 'System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes' or one of its dependencies. The system cannot find the file specified.

请注意,PCL程序集加载得很好,问题是,它只能找不到它依赖(System.Core)。

Please note that PCL assembly was loaded just fine, the problem is, it only can't find its dependencies (System.Core) anymore.

就像Assembly.LoadFile(fileName)是-如果加载的程序集是可移植的,则不行。

It's like Assembly.LoadFile(fileName) is-a no-no if loaded assembly is portable.

有人遇到这个问题吗?有人解决了这个问题吗?

Did anyone have this problem? Did anyone solved this problem?

您可以找到所有文件这里

编辑:
感谢leppie强迫我检查其他选项。我实际上想确保当我回答是的,我尝试过时,我没有在撒谎。显然值得检查。

Thanks to leppie for forcing me to check other options. I actually wanted to be sure that I'm not lying while I answer "Yeah, yeah, I tried". Apparently it was worth checking.

来自苏珊娜·库克的.NET CLR注意事项


请小心-这些不是

Be careful - these aren't the same thing.

LoadFrom()通过Fusion,可以重定向到另一个路径的另一个程序集,但如果已经在LoadFrom上下文中加载了相同的身份,则具有相同的标识。 。
LoadFile()根本不会通过Fusion绑定-加载程序会继续进行并完全加载*调用者所请求的内容。它不使用Load或LoadFrom上下文。

LoadFrom() goes through Fusion and can be redirected to another assembly at a different path but with that same identity if one is already loaded in the LoadFrom context. LoadFile() doesn't bind through Fusion at all - the loader just goes ahead and loads exactly* what the caller requested. It doesn't use either the Load or the LoadFrom context.


推荐答案

<$ c中的平台的 System.Core 程序集(例如,.NET Framework 4.0的版本4.0.0.0 )当要求提供 2.0.5.0 版本时,$ c> AssemblyResolve 事件。

You can return the System.Core assembly of your platform (e.g. version 4.0.0.0 for .NET Framework 4.0) from the AssemblyResolve event, when asked for the 2.0.5.0 version.

我正在通过 Load(byte [])加载所有存储为资源的引用程序集,这也无法解析 2.0.5.0 程序集,我从 AppDomain.CurrentDomain中检索 System System.Core .GetAssemblies()

I am loading all my referenced assemblies stored as resources via Load(byte[]), which also fails to resolve the 2.0.5.0 assembly, and I retrieve both System and System.Core from AppDomain.CurrentDomain.GetAssemblies().

这篇关于“无法加载文件或程序集'System.Core,版本= 2.0.5.0,...”动态加载可移植类库时的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆