Прочитать сборку MethodBody, разобрать ее имя в ListBox и его IL в TextBox?
У меня есть WPF MainWindow
Форма с ListBox
и TextBox
это выглядит так:
Теперь 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, заполненного именами методов
Теперь уловка, которую я хотел бы выбрать для любого метода из 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;