您好,登錄后才能下訂單哦!
==============================================動態編譯程序思路
* 0,把C#以字符串的方式放在string對象里
* 1,實例化一個C#編譯器:CSharpCodeProvider
* 2,創建編譯器環境(并配置環境):CompilerParameters
* 3,開始編譯:ccp.CompileAssemblyFromSource(cp, abc);
* 4,返回編譯結果:CompilerResults
* 【5,可以使用反射調用該程序集】
==============================================什么是程序域?
在.net技術之前,進程做為應用程序獨立的邊界,
.net體系結構中,應用程序有一個新的邊界,就是程序域。可以合理分配對象在不同的程序域中,
可以對程序域進行卸載
==============================================程序域的作用
如果程序集是動態加載的,且需要在使用完后卸載程序集,應用程序域就非常有
用。 在主應用程序域中,不能刪除已加載的程序集,但可以終止應用程序域,在該應
用程序域中載的所有程序集都會從內存中清除。
==============================================例子:
--------------------------------------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(動態編譯程序代碼類)
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(); //編譯參數配置 CompilerParameters cp = new CompilerParameters(); //編譯結果 CompilerResults cr; //控制臺輸出 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; string error = ""; for (int i = 0; i < cr.Errors.Count; i++) { error += string.Format("影響行數:{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"); //非靜態方法需要實例化類 object o = Activator.CreateInstance(t); //獲取方法 MethodInfo m = t.GetMethod("aa"); //執行方法 m.Invoke(o, null); //返回控制臺輸出的結果 return sw.ToString(); } } } }
--------------------------------------AppDomainCode.cs(創建卸載程序域類)
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) { //創建程序域 AppDomain app = AppDomain.CreateDomain("zhangdi"); //創建制定類型的實例 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(); *點擊 點擊我輸出控制臺 按鈕【出現錯誤:調用的目標發生了異常】 *這個錯誤我找了好幾天,坑爹 ************************************* */ public partial class Form1 : Form { public Form1() { InitializeComponent(); } string str = "Console.WriteLine(\"aasdasd\");Console.ReadLine();"; /// <summary> /// 點我輸出控制臺 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> 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; } /// <summary> /// 點我輸出可執行文件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> 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; } } }
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。