==============================================動態(tài)編譯程序思路
創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供興化網(wǎng)站建設(shè)、興化做網(wǎng)站、興化網(wǎng)站設(shè)計、興化網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、興化企業(yè)網(wǎng)站模板建站服務(wù),十多年興化做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。
* 0,把C#以字符串的方式放在string對象里
* 1,實例化一個C#編譯器:CSharpCodeProvider
* 2,創(chuàng)建編譯器環(huán)境(并配置環(huán)境):CompilerParameters
* 3,開始編譯:ccp.CompileAssemblyFromSource(cp, abc);
* 4,返回編譯結(jié)果:CompilerResults
* 【5,可以使用反射調(diào)用該程序集】
==============================================什么是程序域?
在.net技術(shù)之前,進程做為應(yīng)用程序獨立的邊界,
.net體系結(jié)構(gòu)中,應(yīng)用程序有一個新的邊界,就是程序域??梢院侠矸峙鋵ο笤诓煌某绦蛴蛑?,
可以對程序域進行卸載
==============================================程序域的作用
如果程序集是動態(tài)加載的,且需要在使用完后卸載程序集,應(yīng)用程序域就非常有
用。 在主應(yīng)用程序域中,不能刪除已加載的程序集,但可以終止應(yīng)用程序域,在該應(yīng)
用程序域中載的所有程序集都會從內(nèi)存中清除。
==============================================例子:
--------------------------------------CompileType.cs(枚舉文件)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AppDomainDemo { public enum CompileType { Console,//控制臺輸出 File//輸出文件 } }
--------------------------------------CompileCode.cs(動態(tài)編譯程序代碼類)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.Reflection; using Microsoft.CSharp;//提供對 C# 代碼生成器和代碼編譯器的實例的訪問。 using System.CodeDom.Compiler;//用途是對所支持編程語言的源代碼的生成和編譯進行管理 namespace AppDomainDemo { //MarshalByRefObject:跨域訪問必須要繼承此類 public class CompileCode : MarshalByRefObject { public string CompileCodeGo(string input, CompileType ct, out bool IsError) { StringBuilder sb1 = new StringBuilder(); sb1.Append("using System;"); sb1.Append("using System.Windows.Forms;"); sb1.Append("public class Program{public static void Main(string[] args){"); StringBuilder sb2 = new StringBuilder(); sb2.Append("}"); sb2.Append("public void aa(){"); string bottom = "}}"; //編譯器 CSharpCodeProvider ccp = new CSharpCodeProvider(); //編譯參數(shù)配置 CompilerParameters cp = new CompilerParameters(); //編譯結(jié)果 CompilerResults cr; //控制臺輸出 if (ct == CompileType.Console) { //設(shè)置是否在內(nèi)存中生成輸出 cp.GenerateInMemory = true; } else//編譯為可執(zhí)行文件 { //是否是可執(zhí)行文件 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)//編輯結(jié)果出現(xiàn)異常 { IsError = true; string error = ""; for (int i = 0; i < cr.Errors.Count; i++) { error += string.Format("影響行數(shù):{0},錯誤信息:{1}\r\n", cr.Errors[i].Line.ToString(), cr.Errors[i].ErrorText); } return error; } else { IsError = false; //用于接受控制臺輸出的信息 StringWriter sw = new StringWriter(); Console.SetOut(sw); //獲取編譯的程序集[反射] Assembly asb = cr.CompiledAssembly; //獲取類 Type t = asb.GetType("Program"); //非靜態(tài)方法需要實例化類 object o = Activator.CreateInstance(t); //獲取方法 MethodInfo m = t.GetMethod("aa"); //執(zhí)行方法 m.Invoke(o, null); //返回控制臺輸出的結(jié)果 return sw.ToString(); } } } }
--------------------------------------AppDomainCode.cs(創(chuàng)建卸載程序域類)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AppDomainDemo { public class AppDomainCode { public string AppDomainCodeGo(string input, CompileType ct, out bool IsError) { //創(chuàng)建程序域 AppDomain app = AppDomain.CreateDomain("zhangdi"); //創(chuàng)建制定類型的實例 CompileCode cc = (CompileCode)app.CreateInstanceAndUnwrap("AppDomainDemo", "AppDomainDemo.CompileCode"); string result= cc.CompileCodeGo(input, ct, out IsError); //卸載程序域 AppDomain.Unload(app); return result; } } }
--------------------------------------Form1.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; namespace AppDomainDemo { /* ************************************* *代碼不能為Console.ReadKey(); *點擊 點擊我輸出控制臺 按鈕【出現(xiàn)錯誤:調(diào)用的目標發(fā)生了異?!? *這個錯誤我找了好幾天,坑爹 ************************************* */ public partial class Form1 : Form { public Form1() { InitializeComponent(); } string str = "Console.WriteLine(\"aasdasd\");Console.ReadLine();"; ////// 點我輸出控制臺 /// /// /// private void btnConsole_Click(object sender, EventArgs e) { AppDomainCode adc = new AppDomainCode(); bool iserror; string result = adc.AppDomainCodeGo(str, CompileType.Console, out iserror); richTextBox1.Text = result; } ////// 點我輸出可執(zhí)行文件 /// /// /// private void btnFile_Click(object sender, EventArgs e) { AppDomainCode adc = new AppDomainCode(); bool iserror; string result = adc.AppDomainCodeGo(str, CompileType.File, out iserror); richTextBox1.Text = result; } } }