在设计模式的策略模式中,需要动态加载程序集信息,本文通过一个简单的实例,来讲解动态加载Dll需要的知识点。下面跟着小编一起来看下吧
在设计模式的策略模式中,需要动态加载程序集信息,本文通过一个简单的实例,来讲解动态加载Dll需要的知识点。下面跟着小编一起来看下吧
在设计模式的策略模式中,需要动态加载程序集信息,本文通过一个简单的实例,来讲解动态加载Dll需要的知识点。下面跟着小编一起来看下吧
在设计模式的策略模式中,需要动态加载程序集信息,本文通过一个简单的实例,来讲解动态加载dll需要的知识点。
涉及知识点:
如下图所示:
具体代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
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()); } } |
动态加载和反射调用的功能还有很多,不能一一列举,只能在以后的工作中用到时再加以研究。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持米米素材网!
原文链接:http://www.cnblogs.com/hsiang/p/6505568.html
发表评论