在设计模式的策略模式中,需要动态加载程序集信息,本文通过一个简单的实例,来讲解动态加载dll需要的知识点。
涉及知识点:
如下图所示:
具体代码如下:
public partial class dllloadform : form { public dllloadform() { initializecomponent(); } private void btnopenfile_click(object sender, eventargs e) { openfiledialog ofd = new openfiledialog() { multiselect=false, filter = "dll info|*.dll|all files|*.*", initialdirectory=appdomain.currentdomain.basedirectory, title="dll信息", tag="请选择" }; if (ofd.showdialog() == dialogresult.ok) { this.txtdllfile.text = ofd.filename; } } private void btnloaddll_click(object sender, eventargs e) { if (string.isnullorempty(this.txtdllfile.text.trim())) { messagebox.show("请选择dll文件"); return; } loaddllinfo(this.txtdllfile.text); } /// <summary> /// 动态加载dll /// </summary> /// <param name="dllpath">需要加载的dll的路径</param> public void loaddllinfo(string dllpath) { if (file.exists(dllpath)) { treenodecollection tvnodes = tvdllinfo.nodes; tvnodes.clear(); tvnodes.add("dllinfo"); assemblyname dllassemblyname = assemblyname.getassemblyname(dllpath); assembly dllassembly = assembly.load(dllassemblyname); module[] modules = dllassembly.getmodules();//获取作为程序集一部分的所有模块信息 type[] types = dllassembly.gettypes();//获取程序集中定义的所有类型 assemblyname[] referrenceasseblies = dllassembly.getreferencedassemblies();//获取程序集引用的程序集信息 tvnodes[0].nodes.add("基本信息"); string dllfullname = dllassembly.fullname; bool isglobalasseblycache = dllassembly.globalassemblycache;//是否从全局程序集加载 bool isfulltrusted = dllassembly.isfullytrusted;//是否已完全信任方式加载的 module manifestmodule = dllassembly.manifestmodule;//获取清单模块 bool isreflectiononly = dllassembly.reflectiononly;//是否加载到只反射模块中 //更新到节点 tvnodes[0].nodes[0].nodes.add(string.format("全路径:{0}", dllfullname)); tvnodes[0].nodes[0].nodes.add(string.format("是否全局程序集:{0}", isglobalasseblycache)); tvnodes[0].nodes[0].nodes.add(string.format("是否全信任:{0}", isfulltrusted)); tvnodes[0].nodes[0].nodes.add(string.format("是否只反射:{0}", isreflectiononly)); tvnodes[0].nodes[0].nodes.add(string.format("清单模块:{0}", manifestmodule.name)); ienumerable<type> exportedtypes = dllassembly.exportedtypes;//公共类型集合 tvnodes[0].nodes.add("模块信息"); int i = 0; foreach (var module in modules) { fieldinfo[] fields = module.getfields();//返回模块中定义的全局字段 methodinfo[] methods = module.getmethods();//返回模块中定义的全局方法 type[] mtypes = module.gettypes();//返回模块中定义的类型集合 bool isresource = module.isresource();//指示此模块是否是资源 int mdstreamversion = module.mdstreamversion;//获取源数据流的版本 guid versionid = module.moduleversionid;//获取模块的版本id string modulename = module.name;//获取模块的名称,去除路径的 int metadatatoken = module.metadatatoken; string scopename = module.scopename; tvnodes[0].nodes[1].nodes.add(string.format("模块:{0}", modulename)); tvnodes[0].nodes[1].nodes[i].nodes.add(string.format("数据流版本:{0}", mdstreamversion)); tvnodes[0].nodes[1].nodes[i].nodes.add(string.format("是否资源:{0}", isresource)); tvnodes[0].nodes[1].nodes[i].nodes.add(string.format("版本id:{0}", versionid)); tvnodes[0].nodes[1].nodes[i].nodes.add(string.format("metadata:{0}", metadatatoken)); tvnodes[0].nodes[1].nodes[i].nodes.add(string.format("scopename:{0}", scopename)); tvnodes[0].nodes[1].nodes[i].nodes.add(getnodes<fieldinfo>(fields, "公共字段")); tvnodes[0].nodes[1].nodes[i].nodes.add(getnodes<methodinfo>(methods, "mehods")); //tvnodes[0].nodes[1].nodes[i].nodes.add(string.format("types:{0}", string.join(",", mtypes.select(p => p.name)))); i++; } tvnodes[0].nodes.add("类型信息"); i = 0; foreach (var type in types) { typeattributes typeattributes = type.attributes;//与type关联的属性 string typefullname = type.fullname;//获取类型的完全限定名称 fieldinfo[] typefields = type.getfields();//获取所有的公共字段 eventinfo[] typeevents = type.getevents();//获取所有的 公共事件 type[] typeinterfaces = type.getinterfaces();//获取所有的公共接口 memberinfo[] typemembers = type.getmembers();//获取所有的公共成员 methodinfo[] typemethods = type.getmethods();//获取所有的公共方法 typeinfo typeinfo = type.gettypeinfo();//返回指定类型的表述形式 string namespace = type.namespace; //指定类型的命名空间 string typename = type.name;//获取当前成员的名称 constructorinfo[] typeconstructors = type.getconstructors();//类型的构造函数 tvnodes[0].nodes[2].nodes.add(string.format("类型:{0}", typename)); tvnodes[0].nodes[2].nodes[i].nodes.add(string.format("全名称:{0}", typefullname)); tvnodes[0].nodes[2].nodes[i].nodes.add(string.format("制定类型名称:{0}", typeinfo.name)); tvnodes[0].nodes[2].nodes[i].nodes.add(string.format("命名空间:{0}", namespace)); tvnodes[0].nodes[2].nodes[i].nodes.add(string.format("接口:{0}", string.join(",", typeinterfaces.select(p => p.name)))); tvnodes[0].nodes[2].nodes[i].nodes.add(getnodes<fieldinfo>(typefields, "公共字段")); tvnodes[0].nodes[2].nodes[i].nodes.add(getnodes<constructorinfo>(typeconstructors, "构造函数")); tvnodes[0].nodes[2].nodes[i].nodes.add(getnodes<eventinfo>(typeevents, "事件")); tvnodes[0].nodes[2].nodes[i].nodes.add(getnodes<memberinfo>(typemembers, "成员member")); tvnodes[0].nodes[2].nodes[i].nodes.add(getnodes<methodinfo>(typemethods, "公共方法")); i++; } } } /// <summary> /// 通过类型获取节点 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="lstinfos"></param> /// <param name="name"></param> /// <returns></returns> public treenode getnodes<t>(t[] lstinfos, string name) where t : memberinfo { treenode tnode = new treenode(name); foreach (var t in lstinfos) { tnode.nodes.add(t.name); } return tnode; } /// <summary> /// 调用静态方法的例子 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btncallstaticbyreflection_click(object sender, eventargs e) { assemblyname assemblyname = assemblyname.getassemblyname("testassembly.exe"); assembly assembly = assembly.load(assemblyname); type t = assembly.gettype("testassembly.program", true, true); //object o= activator.createinstance(t, false); methodinfo methodinfo = t.getmethod("main",bindingflags.static|bindingflags.public); methodinfo.invoke(null,new string[][] { new string[] { "g" } }); } /// <summary> /// 调用非静态方法的例子 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btncallfunctionbyreflection_click(object sender, eventargs e) { assemblyname assemblyname = assemblyname.getassemblyname("testassembly.exe");//此处是相对路径 assembly assembly = assembly.load(assemblyname); type t = assembly.gettype("testassembly.program", true, true); object o = activator.createinstance(t, false); methodinfo methodinfo = t.getmethod("testassembly", bindingflags.instance|bindingflags.public); object tmp= methodinfo.invoke(o,null); messagebox.show(tmp.tostring()); } }
动态加载和反射调用的功能还有很多,不能一一列举,只能在以后的工作中用到时再加以研究。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持移动技术网!
如对本文有疑问, 点击进行留言回复!!
使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序)
C#实现获取本地内网(局域网)和外网(公网)IP地址的方法分析
网友评论