c# 動態編譯CodeDomProvider.CompileAssemblyFromSource(CompilerParameters cp,string code)

1.使用c#動態編譯,可參考以下:c#

//生成c#代碼
string code = GenerateCode();
CodeDomProvider cdp = CodeDomProvider.CreateProvider("C#");

// 編譯器的參數 
CompilerParameters cp = new CompilerParameters();
cp.ReferencedAssemblies.Add(typeof(T).Assembly.Location);
cp.ReferencedAssemblies.Add("System.Core.dll");//添加引用
foreach (var ass in typeof(T).Assembly.GetReferencedAssemblies())
{
    if (ass.Name != "System.Core")
    {
        var refAss = AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault(assembly => assembly.GetName().Name == ass.Name);
        if (refAss != null)
            cp.ReferencedAssemblies.Add(refAss.Location);
    }
}
//GenerateExecutable是設置編譯後生成的是dll仍是exe,true是dll,false是exe,默認是生成dll的
cp.GenerateExecutable = false;
//對於GenerateInMemory這個屬性,MSDN上說的是true就把編譯的生成的程序集保留在內存中,
//經過CompilerResults實例的CompiledAssembly能夠獲取。若是設爲false則是生成文件保存在磁盤上,
//經過CompilerResults實例的PathToAssembly實例獲取程序集的路徑。事實是,不管GenerateInMemory設置哪一個值,
//都會在硬盤上生成相應的文件,區別在於OutputAssembly設置了相應的文件名的話,生成的文件會存在指定路徑上,
//不然會存放在系統的臨時文件夾裏面
cp.GenerateInMemory = true;
//此處若是不加,在某些狀況下,默認生成的cp.TempFiles.BasePath=C:\Users\Administrator\AppData\Local\Temp\2\j2uudvfi,而不是
//cp.TempFiles.BasePath=C:\Users\Administrator\AppData\Local\Temp\j2uudvfi,因爲\2這一層級的文件夾未建立,致使拋出
//"未能找到路徑……的一部分"的異常,此處初始化一下cp.TempFiles,則可避免此問題
cp.TempFiles = new TempFileCollection(System.IO.Path.GetTempPath());
CompilerResults cr = cdp.CompileAssemblyFromSource(cp, code);

//動態編譯出錯時
if (cr.Errors.HasErrors)
{
    Exception ex = new Exception();
    ex.Data["code"] = code;
    throw ex;
}
else
{
    // 編譯後的程序集 
    Assembly ass = cr.CompiledAssembly;
    //Namespace是命名空間,Class是類名,賦值爲須要的
    Type type = ass.GetType(string.Format("{0}.{1}", Namespace, Class));
    MethodInfo objectToString = type.GetMethod("ObjectToString");
    //動態執行的方法
    structToStringExecutor = new DynamicMethodExecutor(objectToString);
}
相關文章
相關標籤/搜索