读取程序集 MethodBody,在 ListBox 中解析它的名称,在 TextBox 中解析它的 IL?

Read assembly MethodBody, parse its Name in a ListBox and its IL in a TextBox?

我有一个带有 ListBoxTextBox 的 WPF MainWindow 表单,如下所示:

Figure A. WPF MainWindow with Sample Text.

现在,Load Assembly... OnClick 按钮事件允许我 select .NET 程序集并使用 DnLib[= 加载它21=]

然后,如果我想显示方法主体,我会这样做:

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,结果如下:

Figure B. Showing the ListBox Filled with Methods Names

现在是技巧部分,我想从 ListBox select 的任何方法中显示其各自的 MethodBody IL 在 TextBox

我怎样才能实现这样的目标?

«呸!»终于解决了!

这是为将来尝试做同样事情的人提供的解决方案。

Make an instance of 'List' and then iterate through the methods and assign the names to such list, then whenever your SelectedItem index value changes, I can simply call GetMethodBodyByName and then I can surely solve this issue

函数的实现方法如下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 "";
    }

The idea is that 'GetMethodBodyByName' will receive the method name as a parameter, then it will iterate through methods and see if a method matches the given name, then if found, the function will just simply iterate through that method and output the method's body.

这是我的 ListBox_SelectedItemChanged 活动的样子:

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

这就是所有人!

注意:执行此方法时要小心,就像在请求名称时一样,不同的方法可以具有相同的名称。但那是另一天的蛋糕,我现在完成了!保重再见!


为最终解决方案而努力!

WPF MainWindow Forms 本身带有两个有用的小属性,它们是:TagContent,其思想如下:

With the Tag and Content Property we can assign any values to it that later it can be retrieved On-The-Fly without having to depend on Methods names specifically for this task.

所以你不需要循环每个方法并分别获取它的名字,你可以像我一样做:

Iterate through the Method, and assign its body to the Tag property, and its name to the Content property, as this last property is the one that handles the actual Title property, so disregarding anything you do with the method in the future and even if it had the same name of another one, it will work no matter what.

我们如何实现它?

简单:

<...>
// 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 索引值更改事件中输入:

            MSILTextBox.Clear();
            // Retrieve 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;