Исключение «Не удалось загрузить файл или сборку» System.Core, Version = 2.0.5.0,… »при динамической загрузке Portable Class Library

Прежде всего я должен подчеркнуть, что это немного другой вопрос, чем вэта тема, Дополнительно установкаKB2468871 не помогает

Я постарался максимально упростить эту проблему. В общем, речь идет о загрузке сборок PCL в настольном приложении с Assembly.LoadFile (...).

Допустим, есть консольное приложение .NET 4.0 (называемое «C»). Он ссылается на сборку .NET 4.0 (называемую «N4») и сборку PCL (называемую «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 выглядит так:

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);
            }
        }
    }
}

При запуске этого приложения вы получаете абсолютно правильные результаты:

N4: HELLO FROM N4
PCL: HELLO FROM PCL

Давайте добавим событие AssemblyResolve к CurrentDomain в 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».

Давайте перейдем в папку приложения и переименуем «N4.dll» в «N4.data» и запустим «C.exe».

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

Таким образом, он проходит через AssemblyResolve и, наконец, загружает «N4.data» и работает так же хорошо, как оригинал.

Давайте вернем "N4.data" в "N4.dll" и переименуем "PCL.dll" в "PCL.data" и ...

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) больше.

Это похоже на Assembly.LoadFile (fileName), если нет, если загруженная сборка переносима.

У кого-нибудь была эта проблема? Кто-нибудь решил эту проблему?

Вы можете найти все файлыВот.

РЕДАКТИРОВАТЬ: Спасибо Леппи за то, что заставил меня проверить другие варианты. Я действительно хотел быть уверен, что я не лгу, пока отвечаю: «Да, да, я пытался». Видимо это стоило проверить.

Из.NET CLR Заметки Сюзанны Кук:

Будьте осторожны - это не одно и то же.

LoadFrom () проходит через Fusion и может быть перенаправлен на другую сборку по другому пути, но с тем же идентификатором, если он уже загружен в контексте LoadFrom. LoadFile () вообще не связывается через Fusion - загрузчик просто идет вперед и загружает ровно * то, что запросил вызывающий. Он не использует ни контекст Load, ни LoadFrom.

Ответы на вопрос(3)

Ваш ответ на вопрос