C#窗体编程实现程序集查看器

前言:

今天,没有话可说,直接上代码。

题目描述:

C#窗体编程实现程序集查看器_第1张图片

 效果展示:

C#窗体编程实现程序集查看器_第2张图片

代码:

From1.cs

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;
        }
    }
}

MyUtil.cs

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#的窗体编程、文件的获取、自底向上的编程思)。以前只是知道面向接口编程,但是却没怎么实践过,通过这次面向接口编程,我体会到了接口的强大之处。

 

你可能感兴趣的:(C#)