Подтвердить что ты не робот

Отладка кода из динамически загружаемой сборки в .net core 2.0

У меня есть консольное приложение .net core 2.0, которое делает следующее (упрощенное):

var a = Assembly.Load(Assembly.GetEntryAssembly()
                              .GetReferencedAssemblies()
                              .First(i => i.Name == "MyAssembly"));

var t = a.GetType("MyType");
var i = (MyBaseType)Activator.CreateInstance(t);

i.Execute();

Когда я отлаживаю код, он переходит в MyType.Execute(), как ожидалось.

Однако, если я загружу сборку с помощью следующего кода:

var path = new FileInfo(Assembly.GetExecutingAssembly().Location);
var a = Assembly.LoadFile(Path.Combine(path.DirectoryName, "MyAssembly.dll"));

Код по-прежнему работает, но я не могу войти в MyType.Execute() во время отладки.

Любая идея, почему/что не так?

4b9b3361

Ответ 1

Это может быть вызвано тем, что приложение не может найти файл PDB, связанный с сборкой MyAssembly, как указано в одном из комментариев. Однако кажется, что файл PDB не требуется в той же папке, что и сборка для выполнения работы отладки.

Чтобы проверить, загружены ли символы, установите точку останова в строке сразу после вызова Assembly.LoadFile() и откройте окно Модули (его можно найти в меню "Отладка\Windows" в Visual Studio), В этом окне найдите значение MyAssembly и подтвердите значение в столбце Состояние символа. Если причиной является отсутствие PDB, значение будет "Невозможно найти или открыть файл PDB". Вы также можете использовать это окно, чтобы увидеть, где отладчик попытался найти файл символов.

Отладчик ищет файлы PDB в нескольких местах, как описано здесь: Укажите символ (.pdb) и исходные файлы в отладчике Visual Studio.

В соответствии с этой статьей местоположения по умолчанию для PDB файла:

  • Местоположение, указанное внутри самой сборки (размещается там компоновщиком при сборке сборки)
  • Папка, в которой находится динамически загруженная сборка
  • Папки локального каталога символов
  • Интернет, сеть или локальные серверы символов

Я полагаю, что в вашем случае следует учитывать первое или второе указанное место.

Еще одна важная вещь, которую следует заметить, заключается в том, что PDB должен точно соответствовать сборке, поэтому после перекомпиляции сборки PDB файл также должен быть обновлен в соответствии с новой версией.

Если файл PDB соответствует сборке и находится в одном из указанных мест, вы должны иметь возможность отлаживать код.

Могут быть и другие причины, и это напрямую не связано с тем, что используется .NET Core, но я полагаю, что правильная загрузка PDB может быть проверена.

Ответ 2

Вы проверили опцию только мой код?

введите описание изображения здесь

Включить только мой код

( "Мой код" ), игнорируя системный код и другой код, который оптимизирован или не имеет отладочных символов. Отладчик отображает и выполняет шаги в код пользователя

Может быть, он должен быть снят флажок?

Ответ 3

Я согласен с ответами Лукаша и Алексана. Если вы их проверили, и это не сработает, причина, по которой ваши примеры кода отличаются, может заключаться в том, что они не загружают одну и ту же сборку.

Выполняющая сборка и сборка не всегда являются одной и той же сборкой, поэтому пути могут быть разными. Также может быть загружена другая версия сборки, например, из GAC. Используя окно модулей в Visual Studio, вы можете увидеть, какая DLL загружена. Если правильный PDB присутствует и Just My Code выключен, вы должны войти в него.

Ответ 4

Существует переопределение "Assembly.Load", которое принимает данные PDB в качестве параметра. Вам нужно явно загружать символы отладки.

Отметьте это сообщение SO: Отладка динамически загруженной сборки

Также проверьте это на MSDN: https://msdn.microsoft.com/en-us/library/twt16z2x(v=vs.110).aspx

Надеюсь, что это поможет

Ответ 5

Этот код не будет компилироваться, если вы используете способ Assembly.LoadFile.

Я создал образец проекта в сообществе Visual studio 2017, и мне удалось войти в функцию из динамической сборки, используя способы Assembly.LoadFile и Assembly.Load. Я не пошел с вами, потому что он не компилировался, но я предоставил решение, которое, я думаю, решит вашу проблему.

Вот решение: Полное рабочее решение здесь https://github.com/beyazc/.netcore-dynamic-assembly-debug

В основном я смог отлаживать свой следующий код. Вы должны нажать f11 при вызове метода

var assemlies = Assembly.GetEntryAssembly().GetReferencedAssemblies();
        var assemblyName = "";
        foreach (var item in assemlies)
        {
            if (item.Name == "RefProj")
                assemblyName = item.Name;

        }
        var path = new FileInfo(Assembly.GetExecutingAssembly().Location);
        var a = Assembly.LoadFile(Path.Combine([email protected]"{path}\..\..\..\..\..\RefProj\bin\Debug\netstandard2.0", "RefProj.dll"));
        var t = a.GetType("RefProj.Class1");

        var i = Activator.CreateInstance(t);
        MethodInfo mi = t.GetMethod("get1");
        mi.Invoke(i, null);