动态编译程序与创建卸载程序域
==============================================动态编译程序思路
* 0,把C#以字符串的方式放在string对象里
* 1,实例化一个C#编译器:CSharpCodeProvider
* 2,创建编译器环境(并配置环境):CompilerParameters
* 3,开始编译:ccp.CompileAssemblyFromSource(cp, abc);
* 4,返回编译结果:CompilerResults
* 【5,可以使用反射调用该程序集】
==============================================什么是程序域?
在.net技术之前,进程做为应用程序独立的边界,
.net体系结构中,应用程序有一个新的边界,就是程序域。可以合理分配对象在不同的程序域中,
可以对程序域进行卸载
==============================================程序域的作用
如果程序集是动态加载的,且需要在使用完后卸载程序集,应用程序域就非常有
用。 在主应用程序域中,不能删除已加载的程序集,但可以终止应用程序域,在该应
用程序域中载的所有程序集都会从内存中清除。
==============================================例子:
--------------------------------------CompileType.cs(枚举文件)
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespaceAppDomainDemo{publicenumCompileType{Console,//控制台输出File//输出文件}}
--------------------------------------CompileCode.cs(动态编译程序代码类)
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.IO;usingSystem.Reflection;usingMicrosoft.CSharp;//提供对C#代码生成器和代码编译器的实例的访问。usingSystem.CodeDom.Compiler;//用途是对所支持编程语言的源代码的生成和编译进行管理namespaceAppDomainDemo{//MarshalByRefObject:跨域访问必须要继承此类publicclassCompileCode:MarshalByRefObject{publicstringCompileCodeGo(stringinput,CompileTypect,outboolIsError){StringBuildersb1=newStringBuilder();sb1.Append("usingSystem;");sb1.Append("usingSystem.Windows.Forms;");sb1.Append("publicclassProgram{publicstaticvoidMain(string[]args){");StringBuildersb2=newStringBuilder();sb2.Append("}");sb2.Append("publicvoidaa(){");stringbottom="}}";//编译器CSharpCodeProviderccp=newCSharpCodeProvider();//编译参数配置CompilerParameterscp=newCompilerParameters();//编译结果CompilerResultscr;//控制台输出if(ct==CompileType.Console){//设置是否在内存中生成输出cp.GenerateInMemory=true;}else//编译为可执行文件{//是否是可执行文件cp.GenerateExecutable=true;//配置输出文件路径cp.OutputAssembly=Directory.GetCurrentDirectory()+"/"+DateTime.Now.ToString("yyyyMMhhddmmss")+".exe";}//引用程序集cp.ReferencedAssemblies.Add("System.Windows.Forms.dll");//编译cr=ccp.CompileAssemblyFromSource(cp,sb1.ToString()+input+sb2.ToString()+input+bottom);if(cr.Errors.HasErrors)//编辑结果出现异常{IsError=true;stringerror="";for(inti=0;i<cr.Errors.Count;i++){error+=string.Format("影响行数:{0},错误信息:{1}\r\n",cr.Errors[i].Line.ToString(),cr.Errors[i].ErrorText);}returnerror;}else{IsError=false;//用于接受控制台输出的信息StringWritersw=newStringWriter();Console.SetOut(sw);//获取编译的程序集[反射]Assemblyasb=cr.CompiledAssembly;//获取类Typet=asb.GetType("Program");//非静态方法需要实例化类objecto=Activator.CreateInstance(t);//获取方法MethodInfom=t.GetMethod("aa");//执行方法m.Invoke(o,null);//返回控制台输出的结果returnsw.ToString();}}}}
--------------------------------------AppDomainCode.cs(创建卸载程序域类)
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespaceAppDomainDemo{publicclassAppDomainCode{publicstringAppDomainCodeGo(stringinput,CompileTypect,outboolIsError){//创建程序域AppDomainapp=AppDomain.CreateDomain("zhangdi");//创建制定类型的实例CompileCodecc=(CompileCode)app.CreateInstanceAndUnwrap("AppDomainDemo","AppDomainDemo.CompileCode");stringresult=cc.CompileCodeGo(input,ct,outIsError);//卸载程序域AppDomain.Unload(app);returnresult;}}}
--------------------------------------Form1.cs(窗体后台程序)
usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Windows.Forms;namespaceAppDomainDemo{/***************************************代码不能为Console.ReadKey();*点击点击我输出控制台按钮【出现错误:调用的目标发生了异常】*这个错误我找了好几天,坑爹**************************************/publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}stringstr="Console.WriteLine(\"aasdasd\");Console.ReadLine();";///<summary>///点我输出控制台///</summary>///<paramname="sender"></param>///<paramname="e"></param>privatevoidbtnConsole_Click(objectsender,EventArgse){AppDomainCodeadc=newAppDomainCode();booliserror;stringresult=adc.AppDomainCodeGo(str,CompileType.Console,outiserror);richTextBox1.Text=result;}///<summary>///点我输出可执行文件///</summary>///<paramname="sender"></param>///<paramname="e"></param>privatevoidbtnFile_Click(objectsender,EventArgse){AppDomainCodeadc=newAppDomainCode();booliserror;stringresult=adc.AppDomainCodeGo(str,CompileType.File,outiserror);richTextBox1.Text=result;}}}
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。