今天,没有话可说,直接上代码。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Reflection;
namespace AssemblyView
{
public partial class Form1 : Form
{
private Dictionary assemblyMap;
public Form1()
{
InitializeComponent();
Assembly[] assemblies = System.AppDomain.CurrentDomain.GetAssemblies();
assemblyMap = new Dictionary();
for (int i = 0; i < assemblies.Length; i++)
{
Assembly assembly = assemblies[i];
String name = assembly.GetName().ToString();
String simpleName = name.Substring(0, name.IndexOf(','));
treeView2.Nodes.Add(simpleName, simpleName);
assemblyMap.Add(simpleName, assembly);
}
treeView1.ImageList = imageList1;
}
private void button2_Click(object sender, EventArgs e)
{
//clear treeView1
treeView1.Nodes.Clear();
if (String.IsNullOrEmpty(textBox1.Text))
{
if (treeView2.SelectedNode == null)
{
treeView2.SelectedNode = treeView2.Nodes[0];//default selected the index '0'
}
String key = treeView2.SelectedNode.Text;
Assembly assembly = assemblyMap[key];
ParseAssemblyAndPaint(assembly);//paint nodes to the view
}
else
{
String path = textBox1.Text;
Assembly assembly = Assembly.LoadFile(path);//load .exe or .dll file
ParseAssemblyAndPaint(assembly);//paint nodes to the view
}
}
///
/// draw the assembly to the view
///
///
private void ParseAssemblyAndPaint(Assembly assembly)
{
Type[] types = assembly.GetExportedTypes();
//这里需要按照namespace分组,一个namespace是一个childNode
//grouping data in accoding with namespace
Dictionary> nameSpaceNodesMap = new Dictionary>();
for (int i = 0; i < types.Length; i++)
{
String nameSpace = types[i].Namespace;
if (!nameSpaceNodesMap.ContainsKey(nameSpace))
{
nameSpaceNodesMap[nameSpace] = new List();
}
TreeNode node = GetTypeNode(types[i]);//Type to TreeNode
nameSpaceNodesMap[nameSpace].Add(node);
}
//将map中的数据合并成rootChilds
//get rootChilds
TreeNode[] rootChilds = new TreeNode[nameSpaceNodesMap.Count];
int nameSpaceCount = 0;
foreach (String nameSpace in nameSpaceNodesMap.Keys)
{
//找到namespace的子节点,然后实例化一个namespace节点加到rootChilds上
//find the nodes that it contains namespance
List nodes = nameSpaceNodesMap[nameSpace];
rootChilds[nameSpaceCount++] = new TreeNode(nameSpace, 2, 2, nodes.ToArray());//create nameSpaceNode
}
TreeNode rootNode = new TreeNode(assembly.GetName().Name, 1, 1, rootChilds);
treeView1.Nodes.Add(rootNode);
}
private TreeNode GetTypeNode(Type type)
{
TreeNode[] child = new TreeNode[4];
MethodInfo[] methods = type.GetMethods(System.Reflection.BindingFlags.DeclaredOnly
| System.Reflection.BindingFlags.Public
| System.Reflection.BindingFlags.NonPublic
| System.Reflection.BindingFlags.Instance);
PropertyInfo[] properties = type.GetProperties(System.Reflection.BindingFlags.Instance
| System.Reflection.BindingFlags.NonPublic
| System.Reflection.BindingFlags.Public
| System.Reflection.BindingFlags.DeclaredOnly);
EventInfo[] events = type.GetEvents(System.Reflection.BindingFlags.Instance
| System.Reflection.BindingFlags.NonPublic
| System.Reflection.BindingFlags.Public
| System.Reflection.BindingFlags.DeclaredOnly);
ConstructorInfo[] constructors = type.GetConstructors(
System.Reflection.BindingFlags.Instance
| System.Reflection.BindingFlags.NonPublic
| System.Reflection.BindingFlags.Public
| System.Reflection.BindingFlags.DeclaredOnly);
child[0] = UserUtils.ParseMethodsToNode(methods);
child[1] = UserUtils.ParsePropertiesToNode(properties);
child[2] = UserUtils.ParseEventsToNode(events);
child[3] = UserUtils.ParseContructorsToNode(constructors, type.Name);
return new TreeNode(type.Name, 3, 3, child);
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog fileDialog = new OpenFileDialog();
fileDialog.Multiselect = true;
fileDialog.Title = "请选择一个dll文件或者exe文件";
fileDialog.Filter = "dll文件(*.dll)|*.dll" + "|" +
"exe文件(*.exe)|*.exe";
if (fileDialog.ShowDialog() == DialogResult.OK)
{
string file = fileDialog.FileName;
textBox1.Text = file;
}
}
private void treeView2_AfterSelect(object sender, TreeViewEventArgs e)
{
textBox1.Text = "";
}
}
public static class UserUtils
{
private static TreeNode ParseToTreeNode(IInfoTransform info)
{
Object[] attributes = info.GetAttributes();
if (attributes == null)
{
return new TreeNode(info.GetNodeText());
}
TreeNode[] attributeChild = new TreeNode[attributes.Length];
for (int i = 0; i < attributes.Length; i++)
{
attributeChild[i] = new TreeNode(attributes[i].ToString(), 8, 8);
}
return new TreeNode(info.GetNodeText(), attributeChild);
}
//private static
public static TreeNode ParseMethodsToNode(MethodInfo[] methods)
{
TreeNode[] methodsChild = new TreeNode[methods.Length];
for (int i = 0; i < methodsChild.Length; i++)
{
TreeNode node = UserUtils.ParseToTreeNode(new MyMethodInfo(methods[i]));
methodsChild[i] = node;
}
return new TreeNode("methods", 4, 4, methodsChild);
}
public static TreeNode ParsePropertiesToNode(PropertyInfo[] properties)
{
TreeNode[] child = new TreeNode[properties.Length];
for (int i = 0; i < child.Length; i++)
{
TreeNode node = UserUtils.ParseToTreeNode(new MyPropertyInfo(properties[i]));
child[i] = node;
}
return new TreeNode("properties", 5, 5, child);
}
public static TreeNode ParseEventsToNode(EventInfo[] events)
{
TreeNode[] child = new TreeNode[events.Length];
for (int i = 0; i < child.Length; i++)
{
TreeNode node = UserUtils.ParseToTreeNode(new MyEventInfo(events[i]));
child[i] = node;
}
return new TreeNode("events", 6, 6, child);
}
public static TreeNode ParseContructorsToNode(ConstructorInfo[] constructors, String className)
{
TreeNode[] child = new TreeNode[constructors.Length];
for (int i = 0; i < child.Length; i++)
{
TreeNode node = UserUtils.ParseToTreeNode(new MyConstructorInfo(constructors[i], className));
child[i] = node;
}
return new TreeNode(".ctor", 7, 7, child);
}
}
public class MyInfo
{
private String info;
public MyInfo(MethodInfo methodInfo)
{
this.info = methodInfo.ToString();
}
public MyInfo(PropertyInfo propertyInfo)
{
this.info = propertyInfo.Name;
}
public MyInfo(EventInfo eventInfo)
{
this.info = eventInfo.Name;
}
public MyInfo(ConstructorInfo constructorInfo, String className)
{
this.info = constructorInfo.ToString().Replace(".ctor", className);
}
public override string ToString()
{
return this.info;
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Reflection;
using System.Globalization;
namespace AssemblyView
{
public interface IInfoTransform
{
String GetNodeText();
Object[] GetAttributes();
}
public class MyMethodInfo : IInfoTransform
{
private String Info { get; set; }
private Object[] attributes;
public MyMethodInfo(MethodInfo methodInfo)
{
this.Info = methodInfo.ToString();
this.attributes = methodInfo.GetCustomAttributes(false);
}
public Object[] GetAttributes()
{
if(attributes == null)
{
return null;
}
return attributes.Length > 0 ? attributes : null;
}
public string GetNodeText()
{
return this.Info;
}
}
public class MyPropertyInfo : IInfoTransform
{
private String Info { get; set; }
private Object[] attributes;
public MyPropertyInfo(PropertyInfo info)
{
this.Info = info.Name;
this.attributes = info.GetCustomAttributes(false);
}
public string GetNodeText()
{
return this.Info;
}
public Object[] GetAttributes()
{
if (attributes == null)
{
return null;
}
return attributes.Length > 0 ? attributes : null;
}
}
public class MyEventInfo : IInfoTransform
{
private String Info { get; set; }
private Object[] attributes;
public MyEventInfo(EventInfo info)
{
this.Info = info.Name;
this.attributes = info.GetCustomAttributes(false);
}
public string GetNodeText()
{
return this.Info;
}
public Object[] GetAttributes()
{
if (attributes == null)
{
return null;
}
return attributes.Length > 0 ? attributes : null;
}
}
public class MyConstructorInfo : IInfoTransform
{
private String Info { get; set; }
private Object[] attributes;
public MyConstructorInfo(ConstructorInfo info, String className)
{
this.Info = info.ToString().Replace(".ctor", className);
this.attributes = info.GetCustomAttributes(false);
}
public string GetNodeText()
{
return this.Info;
}
public Object[] GetAttributes()
{
if (attributes == null)
{
return null;
}
return attributes.Length > 0 ? attributes : null;
}
}
class MyUtil
{
}
}
通过这次编程学习,我get到了一些新的知识点(C#的窗体编程、文件的获取、自底向上的编程思)。以前只是知道面向接口编程,但是却没怎么实践过,通过这次面向接口编程,我体会到了接口的强大之处。