C#动态编译

来源:互联网 发布:金融专业就业前景知乎 编辑:程序博客网 时间:2024/04/30 08:27

 using System;
using System.IO;
using System.Text;
using System.Reflection;
using System.Diagnostics;
using System.CodeDom.Compiler;
using Microsoft.CSharp;

namespace WindowsApplication1
{
 public class CSharpCodeCompiler
 {
  private ICodeCompiler      _compiler;
  private CompilerParameters _parameters;
  private string             _options;
  private CompilerResults    _complerResults;
  private string             _sourceName;
  private string             _complerErrors;

  private readonly string[] _reference =
      { "System.dll", "System.Data.dll", "System.Xml.dll",
       "System.Drawing.dll", "System.Windows.Forms.dll",
        };

  public CSharpCodeCompiler()
  {
   _compiler       = new CSharpCodeProvider().CreateCompiler();
   _parameters     = new CompilerParameters(_reference);
   _options        = String.Empty;
   _complerResults = null;
   _complerErrors  = String.Empty;
   _sourceName     = String.Empty;
  }

  public string CompilerOptions
  {
   set
   {
    _options = value;
   }
   get
   {
    return _options;
   }

  }

  public CompilerResults CompilerResults
  {
   get
   {
    return _complerResults;
   }
  }

  public string CompilerErrors
  {
   get
   {
    return _complerErrors;
   }
  }

  private string GetCompilerErrorList(CompilerResults results)
  {
   if(_complerResults.Errors.Count == 0)
   {
    return String.Empty;
   }

   StringBuilder sb = new StringBuilder();
   foreach(System.CodeDom.Compiler.CompilerError error in _complerResults.Errors)
   {
    string line = String.Format("{0}({1}) Error {2}: {3}",
     _sourceName, error.Line, error.ErrorNumber, error.ErrorText);
    sb.Append(line);
    sb.Append(Environment.NewLine);
   }
   _sourceName = String.Empty;

   return sb.ToString();
  }


  protected string Compile(ICodeCompiler compiler, string statements, string assemblyPath, bool executable)
  {
   _parameters.GenerateInMemory = false;
   _parameters.GenerateExecutable = executable;
   _parameters.OutputAssembly = assemblyPath;

   if(CompilerOptions.Length > 0)
   {
    _parameters.CompilerOptions = CompilerOptions;
   }

   if(_sourceName == String.Empty)
   {
    _sourceName = assemblyPath;
   }

   _complerResults = compiler.CompileAssemblyFromSource(_parameters, statements);
   _complerErrors = GetCompilerErrorList(_complerResults);
   if(_complerResults.Errors.Count > 0)
   {
    return null;
   }

   return assemblyPath;
  }

  public virtual string Compile(string statements, string assemblyPath, bool executable)
  {
   return Compile(_compiler, statements, assemblyPath, executable);
  }

  public string CompileScriptFile(string sourceFile, string assemblyPath, bool executable)
  {
   string strStatements;

   using(StreamReader st = new StreamReader(sourceFile, System.Text.Encoding.Default))
   {
    strStatements = st.ReadToEnd();
   }
   _sourceName = sourceFile;

   return Compile(strStatements, assemblyPath, executable);
  }

  protected Type Compile(ICodeCompiler compiler, string className, string statements)
  {
   _parameters.GenerateInMemory = true;
   _parameters.GenerateExecutable = false;
   _parameters.OutputAssembly = null;

   if(CompilerOptions.Length > 0)
   {
    _parameters.CompilerOptions = CompilerOptions;
   }

   if(_sourceName == String.Empty)
   {
    _sourceName = className;
   }

   _complerResults = compiler.CompileAssemblyFromSource(_parameters, statements);
   _complerErrors = GetCompilerErrorList(_complerResults);
   if(_complerResults.Errors.Count > 0)
   {
    return null;
   }

   Assembly assembly = _complerResults.CompiledAssembly;
   return assembly.GetType(className);
  }

  public virtual Type Compile(string className, string statements)
  {
   return Compile(_compiler, className, statements);
  }

  public Type CompileScriptFile(string className, string sourceFile)
  {
   string strStatements;

   using(StreamReader st = new StreamReader(sourceFile, System.Text.Encoding.Default))
   {
    strStatements = st.ReadToEnd();
   }
   _sourceName = sourceFile;

   return Compile(className, strStatements);
  }

  public object Invoke(Type type, string methodName, object[] param)
  {
   object objInstance = Activator.CreateInstance(type);

   BindingFlags flag = BindingFlags.InvokeMethod;
   return type.InvokeMember(methodName, flag, null, objInstance, param);
  }
 }
}

/*
string statements= @"using System;

public class Test
{
private string testCode = ""1"";
public string GetString(){return testCode;}
}";
CSharpCodeCompiler comp= new CSharpCodeCompiler();
Type typ= comp.Compile("Test", statements);
object obj = comp.Invoke(typ, "GetString", null);
*/

原创粉丝点击