Прочитать сборку MethodBody, разобрать ее имя в ListBox и его IL в TextBox?

У меня есть WPF MainWindow Форма с ListBox и TextBox это выглядит так:

Рисунок A. Главное окно WPF с образцом текста. Рисунок A. Главное окно WPF с образцом текста.

Теперь Load Assembly... Событие кнопки OnClick позволяет мне выбрать сборку.NET и загрузить ее с помощью DnLib

Затем, если я хочу отобразить тела Methods, я бы сделал это так:

Assembly asm = Assembly.LoadFile(filename);
                foreach (Module mod in asm.GetModules())
                {
                    foreach (Type types in mod.GetTypes())
                    {
                        foreach (MethodInfo mdInfo in types.GetMethods())
                        {
                            listBox.Items.Add(mdInfo.Name);
                        }
                    }
                }

Это добавляет каждое найденное имя метода к ListBox слева, в результате примерно так:

Рисунок B. Отображение ListBox, заполненного именами методов Рисунок B. Отображение ListBox, заполненного именами методов

Теперь уловка, которую я хотел бы выбрать для любого метода из ListBox отобразить соответствующий им MethodBody IL на TextBox

Как я могу достичь такой вещи?

1 ответ

Решение

"Фу!" Наконец-то решили!

Вот решение для тех, кто пытается сделать то же самое в будущем.

Сделайте экземпляр List, а затем переберите методы и присвойте имена такому списку, а затем всякий раз, когда ваш SelectedItem изменения значения индекса, я могу просто позвонить GetMethodBodyByName и тогда я точно смогу решить эту проблему

Вот как реализовать функцию GetMethodBodyByName:

public string GetMethodBodyByName(string methodName)
    {
        ModuleDefMD md = ModuleDefMD.Load(filename);
        foreach (TypeDef type in md.Types)
        {
            foreach (MethodDef method in type.Methods)
            {
                for (int i = 0; i < type.Methods.Count; i++)
                {
                    if (method.HasBody)
                    {
                        if (method.Name == methodName)
                        {
                            var instr = method.Body.Instructions;
                            return String.Join("\r\n", instr);
                        }
                    }
                }
            }
        }
        return "";
    }

Идея состоит в том, что GetMethodBodyByName получит имя метода в качестве параметра, затем он будет перебирать методы и проверять, соответствует ли метод заданному имени, тогда, если он найден, функция просто перебирает этот метод и выводит тело метода,

Вот как мой ListBox_SelectedItemChanged Событие выглядит так:

private void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        textBox.Text = "";
        textBox.Text = GetMethodBodyByName(method[listBox.SelectedIndex].Name);
    }

Это все люди!

Примечание: будьте осторожны при использовании этого подхода, как если бы вы запрашивали имена, разные методы могут иметь одинаковые имена. Но это пирог на другой день, я готов! позаботься пока!


Проложив свой путь к окончательному решению!

Формы MainWindow WPF несут с собой два небольших полезных свойства: Tag а также Content Идея следующая:

С Tag а также Content Свойство мы можем присвоить ему любые значения, чтобы потом его можно было извлечь On-The-Fly без необходимости зависеть от имен методов специально для этой задачи.

Таким образом, вы бы вместо того, чтобы зацикливать каждый метод и получать его имя, соответственно, вы можете просто сделать так, как я:

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

Как мы можем это реализовать?

Просто:

<...>
// Inside Method Body iteration routine...
<...>

var instr = mdInfo.Body.Instructions;

                        // Allocate in a new `ListBoxItem` each method and add it to the current listbox with their
                        // ... respective Tag and Content information... // Many Thanks Kao :D
                        newItem = new ListBoxItem();
                        newItem.Content = mdInfo.Name;
                        newItem.Tag = string.Join("\r\n", instr);

                        method.Add(mdInfo);
                        listBox.Items.Add(newItem);

Тогда на вашем SelectedItem Событие Index-Value-Changed поместите это:

            MSILTextBox.Clear();
            // Retireve them given the selected index...
            // ... the returned value will be the Tag content of the ...
            // ... previously saved item.
            string getTag= ((ListBoxItem)listBox.SelectedItem).Tag.ToString();
            MSILTextBox.Text = getTag;
Другие вопросы по тегам