zoukankan      html  css  js  c++  java
  • C# 动态加载程序集信息

    本文通过一个简单的实例,来讲解动态加载Dll需要的知识点。仅供学习分享使用,如有不足之处,还请指正。

    在设计模式的策略模式中,需要动态加载程序集信息。

    涉及知识点:

    • AssemblyName类,完整描述程序集的唯一标识, 用来表述一个程序集。
    • Assembly类,在System.Reflection命名空间下,表示一个程序集,它是一个可重用、无版本冲突并且可自我描述的公共语言运行时应用程序构建基块。
    • Module类 表述在模块上执行反射,表述一个程序集的模块信息。
    • Type类,在System命名空间下,表示类型声明:类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型。
    • FieldInfo类,发现字段属性并提供对字段元数据的访问权。
    • MethodInfo类,发现方法的属性并提供对方法元数据的访问。
    • EventInfo类,发现事件的属性并提供对事件元数据的访问权。
    • ConstructorInfo类,发现类构造函数的属性并提供对构造函数元数据的访问权。
    • Activator类,包含特定的方法,用以在本地或从远程创建对象类型,或获取对现有远程对象的引用。此类不能被继承。
    • BindingFlags类,指定控制绑定和由反射执行的成员和类型搜索方法的标志。在获取方法时,第二个参数会用到

    效果图

    如下图所示:

    核心代码

    具体代码如下:

      1 public partial class DllLoadForm : Form
      2     {
      3         public DllLoadForm()
      4         {
      5             InitializeComponent();
      6         }
      7 
      8         
      9 
     10         private void btnOpenFile_Click(object sender, EventArgs e)
     11         {
     12             OpenFileDialog ofd = new OpenFileDialog()
     13             {
     14                 Multiselect=false,
     15                 Filter = "Dll Info|*.dll|All Files|*.*",
     16                 InitialDirectory=AppDomain.CurrentDomain.BaseDirectory,
     17                 Title="Dll信息",
     18                 Tag="请选择"
     19             };
     20             if (ofd.ShowDialog() == DialogResult.OK) {
     21                 this.txtDllFile.Text = ofd.FileName;
     22             }
     23         }
     24 
     25         private void btnLoadDll_Click(object sender, EventArgs e)
     26         {
     27             if (string.IsNullOrEmpty(this.txtDllFile.Text.Trim())) {
     28                 MessageBox.Show("请选择dll文件");
     29                 return;
     30             }
     31             LoadDllInfo(this.txtDllFile.Text);
     32         }
     33 
     34         /// <summary>
     35         /// 动态加载Dll
     36         /// </summary>
     37         /// <param name="dllPath">需要加载的Dll的路径</param>
     38         public void LoadDllInfo(string dllPath)
     39         {
     40             if (File.Exists(dllPath))
     41             {
     42                 TreeNodeCollection tvNodes = tvDllInfo.Nodes;
     43                 tvNodes.Clear();
     44                 tvNodes.Add("DllInfo");
     45                 AssemblyName dllAssemblyName = AssemblyName.GetAssemblyName(dllPath);
     46                 Assembly dllAssembly = Assembly.Load(dllAssemblyName);
     47                 Module[] modules = dllAssembly.GetModules();//获取作为程序集一部分的所有模块信息
     48                 Type[] types = dllAssembly.GetTypes();//获取程序集中定义的所有类型
     49                 AssemblyName[] referrenceAsseblies = dllAssembly.GetReferencedAssemblies();//获取程序集引用的程序集信息
     50                 tvNodes[0].Nodes.Add("基本信息");
     51 
     52                 string dllFullName = dllAssembly.FullName;
     53                 bool isGlobalAsseblyCache = dllAssembly.GlobalAssemblyCache;//是否从全局程序集加载
     54                 bool isFullTrusted = dllAssembly.IsFullyTrusted;//是否已完全信任方式加载的
     55                 Module manifestModule = dllAssembly.ManifestModule;//获取清单模块
     56                 bool isReflectionOnly = dllAssembly.ReflectionOnly;//是否加载到只反射模块中
     57                 //更新到节点
     58                 tvNodes[0].Nodes[0].Nodes.Add(string.Format("全路径:{0}", dllFullName));
     59                 tvNodes[0].Nodes[0].Nodes.Add(string.Format("是否全局程序集:{0}", isGlobalAsseblyCache));
     60                 tvNodes[0].Nodes[0].Nodes.Add(string.Format("是否全信任:{0}", isFullTrusted));
     61                 tvNodes[0].Nodes[0].Nodes.Add(string.Format("是否只反射:{0}", isReflectionOnly));
     62                 tvNodes[0].Nodes[0].Nodes.Add(string.Format("清单模块:{0}", manifestModule.Name));
     63                 IEnumerable<Type> exportedTypes = dllAssembly.ExportedTypes;//公共类型集合
     64                 tvNodes[0].Nodes.Add("模块信息");
     65                 int i = 0;
     66                 foreach (var module in modules)
     67                 {
     68                     FieldInfo[] fields = module.GetFields();//返回模块中定义的全局字段
     69                     MethodInfo[] methods = module.GetMethods();//返回模块中定义的全局方法
     70                     Type[] mtypes = module.GetTypes();//返回模块中定义的类型集合
     71                     bool isResource = module.IsResource();//指示此模块是否是资源
     72                     int mdStreamVersion = module.MDStreamVersion;//获取源数据流的版本
     73                     Guid versionId = module.ModuleVersionId;//获取模块的版本ID
     74                     string moduleName = module.Name;//获取模块的名称,去除路径的
     75                     int metadataToken = module.MetadataToken;
     76                     string scopeName = module.ScopeName;
     77                     tvNodes[0].Nodes[1].Nodes.Add(string.Format("模块:{0}", moduleName));
     78                     tvNodes[0].Nodes[1].Nodes[i].Nodes.Add(string.Format("数据流版本:{0}", mdStreamVersion));
     79                     tvNodes[0].Nodes[1].Nodes[i].Nodes.Add(string.Format("是否资源:{0}", isResource));
     80                     tvNodes[0].Nodes[1].Nodes[i].Nodes.Add(string.Format("版本ID:{0}", versionId));
     81                     tvNodes[0].Nodes[1].Nodes[i].Nodes.Add(string.Format("MetaData:{0}", metadataToken));
     82                     tvNodes[0].Nodes[1].Nodes[i].Nodes.Add(string.Format("ScopeName:{0}", scopeName));
     83                     tvNodes[0].Nodes[1].Nodes[i].Nodes.Add(GetNodes<FieldInfo>(fields, "公共字段"));
     84                     tvNodes[0].Nodes[1].Nodes[i].Nodes.Add(GetNodes<MethodInfo>(methods, "Mehods"));
     85                     //tvNodes[0].Nodes[1].Nodes[i].Nodes.Add(string.Format("Types:{0}", string.Join(",", mtypes.Select(p => p.Name))));
     86                     i++;
     87                 }
     88                 tvNodes[0].Nodes.Add("类型信息");
     89                 i = 0;
     90                 foreach (var type in types)
     91                 {
     92                     TypeAttributes typeAttributes = type.Attributes;//与Type关联的属性
     93                     string typeFullName = type.FullName;//获取类型的完全限定名称
     94                     FieldInfo[] typeFields = type.GetFields();//获取所有的公共字段
     95                     EventInfo[] typeEvents = type.GetEvents();//获取所有的 公共事件
     96                     Type[] typeInterfaces = type.GetInterfaces();//获取所有的公共接口
     97                     MemberInfo[] typeMembers = type.GetMembers();//获取所有的公共成员
     98                     MethodInfo[] typeMethods = type.GetMethods();//获取所有的公共方法
     99                     TypeInfo typeInfo = type.GetTypeInfo();//返回指定类型的表述形式
    100                     string nameSpace = type.Namespace; //指定类型的命名空间
    101                     string typeName = type.Name;//获取当前成员的名称
    102                     ConstructorInfo[] typeConstructors = type.GetConstructors();//类型的构造函数
    103                     tvNodes[0].Nodes[2].Nodes.Add(string.Format("类型:{0}", typeName));
    104                     tvNodes[0].Nodes[2].Nodes[i].Nodes.Add(string.Format("全名称:{0}", typeFullName));
    105                     tvNodes[0].Nodes[2].Nodes[i].Nodes.Add(string.Format("制定类型名称:{0}", typeInfo.Name));
    106                     tvNodes[0].Nodes[2].Nodes[i].Nodes.Add(string.Format("命名空间:{0}", nameSpace));
    107                     tvNodes[0].Nodes[2].Nodes[i].Nodes.Add(string.Format("接口:{0}", string.Join(",", typeInterfaces.Select(p => p.Name))));
    108                     tvNodes[0].Nodes[2].Nodes[i].Nodes.Add(GetNodes<FieldInfo>(typeFields, "公共字段"));
    109                     tvNodes[0].Nodes[2].Nodes[i].Nodes.Add(GetNodes<ConstructorInfo>(typeConstructors, "构造函数"));
    110                     tvNodes[0].Nodes[2].Nodes[i].Nodes.Add(GetNodes<EventInfo>(typeEvents, "事件"));
    111                     tvNodes[0].Nodes[2].Nodes[i].Nodes.Add(GetNodes<MemberInfo>(typeMembers, "成员Member"));
    112                     tvNodes[0].Nodes[2].Nodes[i].Nodes.Add(GetNodes<MethodInfo>(typeMethods, "公共方法"));
    113                     i++;
    114 
    115                 }
    116             }
    117         }
    118 
    119         /// <summary>
    120         /// 通过类型获取节点
    121         /// </summary>
    122         /// <typeparam name="T"></typeparam>
    123         /// <param name="lstInfos"></param>
    124         /// <param name="name"></param>
    125         /// <returns></returns>
    126         public TreeNode GetNodes<T>(T[] lstInfos, string name) where T : MemberInfo
    127         {
    128             TreeNode tNode = new TreeNode(name);
    129             foreach (var t in lstInfos)
    130             {
    131                 tNode.Nodes.Add(t.Name);
    132             }
    133             return tNode;
    134         }
    135 
    136         /// <summary>
    137         /// 调用静态方法的例子
    138         /// </summary>
    139         /// <param name="sender"></param>
    140         /// <param name="e"></param>
    141         private void btnCallStaticByReflection_Click(object sender, EventArgs e)
    142         {
    143             AssemblyName assemblyName = AssemblyName.GetAssemblyName("TestAssembly.exe");
    144             Assembly assembly = Assembly.Load(assemblyName);
    145             Type t = assembly.GetType("TestAssembly.Program", true, true);
    146             //object o= Activator.CreateInstance(t, false);
    147             MethodInfo methodInfo = t.GetMethod("Main",BindingFlags.Static|BindingFlags.Public);
    148             methodInfo.Invoke(null,new string[][] { new string[] { "g" } });
    149 
    150         }
    151 
    152         /// <summary>
    153         /// 调用非静态方法的例子
    154         /// </summary>
    155         /// <param name="sender"></param>
    156         /// <param name="e"></param>
    157         private void btnCallFunctionByReflection_Click(object sender, EventArgs e)
    158         {
    159             AssemblyName assemblyName = AssemblyName.GetAssemblyName("TestAssembly.exe");//此处是相对路径
    160             Assembly assembly = Assembly.Load(assemblyName);
    161             Type t = assembly.GetType("TestAssembly.Program", true, true);
    162             object o = Activator.CreateInstance(t, false);
    163             MethodInfo methodInfo = t.GetMethod("TestAssembly", BindingFlags.Instance|BindingFlags.Public);
    164             object tmp=  methodInfo.Invoke(o,null);
    165             MessageBox.Show(tmp.ToString());
    166         }
    167     }
    View Code


    ----------------------------------------------------------------------

    动态加载和反射调用的功能还有很多,不能一一列举,只能在以后的工作中用到时再加以研究。

  • 相关阅读:
    [结题报告]10235 Simply Emirp Time limit: 3.000 seconds
    [杭电ACM]1720A+B Coming
    [结题报告]10041 Vito's Family Time limit: 3.000 seconds
    mysqlvarchar、text 类型到底能存储多大字符?
    mysql项目更换数据源为oralce后项目调整
    Oracle创建定时任务执行函数
    IOS手机访问网页window.location.href跳转新页面第一次可以第二次报错失效
    logrotate日志分割
    查找一批设备的在线情况
    pkill 用法例子
  • 原文地址:https://www.cnblogs.com/hsiang/p/6505568.html
Copyright © 2011-2022 走看看