Как получить доступ к метаданным встроенной сборки с помощью IMetaDataDispenser.OpenScope? - PullRequest
1 голос
/ 27 сентября 2011

У меня есть решение .NET, которое состоит из нескольких проектов.Можно сказать, что один из этих проектов логически является первичным, а все остальные - вторичными.Наша команда решила построить проект следующим образом.Основной проект будет производить сборку (я буду называть ее основной).Сборки всех других проектов являются вторичными, и они будут встроены в качестве ресурса в основной.

Класс SourceCodeForExceptionHelper в основном проекте отвечает за получение исходного исходного кода с использованием файлов PDB для каждого возникшего исключения.,Для этого я использую подход, описанный здесь .Это сработало правильно в моем отдельном доказательстве концепции проекта.Но когда я попытался переместить этот класс в реальное решение, я столкнулся с проблемой: метод IMetaDataDispenser.OpenScope не требует пустой ссылки на путь файла сборки.Конечно, у меня нет такой ссылки ни на одну из Вторичных сборок (потому что их файлы встроены в Первичную).По этой причине я не могу создать объект типа ISymbolReader и прочитать исходный код.Как я могу решить эту проблему?Кстати, проблема еще хуже, потому что мы встраиваем только вторичные сборки без их файлов PDB (хотя мы сделаем это, если это необходимо).

Заранее спасибо за любую помощь и совет!

1 Ответ

3 голосов
/ 30 сентября 2011

Я не думаю, что вы можете сделать это, используя встроенные функции .NET Framework, так как они зависят от физических файлов.Однако существует решение, использующее библиотеку Mono Cecil , поскольку она имеет перегрузки, которые принимают поток в качестве входных данных вместо пути к файлу для своей программы чтения символов.

Вот примерконсольное приложение с именем «TestPdb», которое выдает свой IL-код на консоль, включая информацию о PDB:

using System;
using System.IO;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Pdb;

namespace TestPdb
{
    class Program
    {
        static void Main(string[] args)
        {
            // we use a Stream for the assembly
            AssemblyDefinition asm;
            using (FileStream asmStream = new FileStream("testpdb.exe", FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                asm = AssemblyDefinition.ReadAssembly(asmStream);
            }

            // we use a Stream for the PDB
            using (FileStream symbolStream = new FileStream("testpdb.pdb", FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                asm.MainModule.ReadSymbols(new PdbReaderProvider().GetSymbolReader(asm.MainModule, symbolStream));
            }

            TypeDefinition type = asm.MainModule.GetType("TestPdb.Program");

            foreach (MethodDefinition method in type.Methods)
            {
                Console.WriteLine("Method:" + method.Name);
                foreach (Instruction ins in method.Body.Instructions)
                {
                    Console.WriteLine(" " + ins);
                    if (ins.SequencePoint != null)
                    {
                        Console.WriteLine("  Url:" + ins.SequencePoint.Document.Url);
                        // see http://blogs.msdn.com/b/jmstall/archive/2005/06/19/feefee-sequencepoints.aspx
                        if (ins.SequencePoint.StartLine != 0xFEEFEE)
                        {
                            Console.WriteLine("  StartLine:" + ins.SequencePoint.StartLine + " StartColumn:" + ins.SequencePoint.StartColumn);
                            Console.WriteLine("  EndLine:" + ins.SequencePoint.EndLine + " EndColumn:" + ins.SequencePoint.EndColumn);
                        }
                        // etc...
                    }
                }
            }   
        }
    }
}

ПРИМЕЧАНИЕ: поскольку вам нужно только читать из PDB, вы можете перекомпилировать библиотеку Cecil, определяющую условное выражение READ_ONLYсимвол, чтобы сохранить несколько байтов.Вы также можете встраивать исходный код Cecil непосредственно в свои сборки, не нужно использовать версии .DLL.

...