2012-04-25 104 views
0

以下是我的代码:试图以编程方式编译和执行C#代码

using System; 
using System.Collections.Generic; 
using System.Text; 

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

namespace DynaCode 
{ 

class Program 
{ 

    static void Main(string[] args) 
    { 

     string content = File.ReadAllText(@"D:\hi.cs"); 
     string[] code = new string[content.Length]; 
     char[] seperators = { '\n','\r','\t' }; 
     code = content.Split(seperators); 


     CompileAndRun(code); 

     Console.ReadKey(); 

    } 

    static void CompileAndRun(string[] code) 
    { 
     CompilerParameters CompilerParams = new CompilerParameters(); 
     string outputDirectory = Directory.GetCurrentDirectory(); 

     CompilerParams.GenerateInMemory = true; 
     CompilerParams.TreatWarningsAsErrors = false; 
     CompilerParams.GenerateExecutable = false; 
     CompilerParams.CompilerOptions = "/optimize"; 

     string[] references = { "System.dll"}; 

     CompilerParams.ReferencedAssemblies.AddRange(references); 

     CSharpCodeProvider provider = new CSharpCodeProvider(); 
     CompilerResults compile = provider.CompileAssemblyFromSource(CompilerParams, code); 

     if (compile.Errors.HasErrors) 
     { 
      string text = "Compile error: "; 
      foreach (CompilerError ce in compile.Errors) 
      { 
       text += "rn" + ce.ToString(); 
      } 
      throw new Exception(text); 
     } 

     //ExpoloreAssembly(compile.CompiledAssembly); 

     Module module = compile.CompiledAssembly.GetModules()[0]; 
     Type mt = null; 
     MethodInfo methInfo = null; 

     if (module != null) 
     { 
      mt = module.GetType("DynaCore.DynaCore"); 
     } 

     if (mt != null) 
     { 
      methInfo = mt.GetMethod("Main"); 
     } 

     if (methInfo != null) 
     { 
      Console.WriteLine(methInfo.Invoke(null, new object[] { "here in dyna code" })); 
     } 
    } 

    static void ExpoloreAssembly(Assembly assembly) 
    { 
     Console.WriteLine("Modules in the assembly:"); 
     foreach (Module m in assembly.GetModules()) 
     { 
      Console.WriteLine("{0}", m); 

      foreach (Type t in m.GetTypes()) 
      { 
       Console.WriteLine("t{0}", t.Name); 

       foreach (MethodInfo mi in t.GetMethods()) 
       { 
        Console.WriteLine("tt{0}", mi.Name); 
       } 
      } 
     } 
    } 
} 
} 

的hi.cs文件的内容如下:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO; 



namespace DynaCore 
{ 
class DynaCore 
{ 
    static public void Main(string[] args) 
    { 

    Console.WriteLine("hello, this is good"); 

    } 
} 
} 

这是我得到时错误我尝试运行此程序:

System.Exception was unhandled 
    Message="Compile error: rnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.16.cs(1,19) : error CS1514: { expectedrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.16.cs(1,19) : error CS1513: } expectedrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.18.cs(1,1) : error CS0116: A namespace does not directly contain members such as fields or methodsrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.20.cs(1,19) : error CS1514: { expectedrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.20.cs(1,19) : error CS1513: } expectedrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.20.cs(1,11) : error CS0101: The namespace '<global namespace>' already contains a definition for 'DynaCore'rnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.22.cs(1,5) : error CS0116: A namespace does not directly contain members such as fields or methodsrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.24.cs(1,23) : error CS1518: Expected class, delegate, enum, interface, or structrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.24.cs(1,40) : error CS1001: Identifier expectedrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.24.cs(1,42) : error CS1518: Expected class, delegate, enum, interface, or structrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.26.cs(1,9) : error CS0116: A namespace does not directly contain members such as fields or methodsrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.30.cs(1,10) : error CS0116: A namespace does not directly contain members such as fields or methodsrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.35.cs(1,9) : error CS1022: Type or namespace definition, or end-of-file expectedrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.37.cs(1,5) : error CS1022: Type or namespace definition, or end-of-file expectedrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.39.cs(1,1) : error CS1022: Type or namespace definition, or end-of-file expected" 
    Source="Compiling" 
    StackTrace: 
     at DynaCode.Program.CompileAndRun(String[] code) in C:\Documents and Settings\simonjef\My Documents\Visual Studio 2008\Projects\Compiling\Compiling\Program.cs:line 72 
     at DynaCode.Program.Main(String[] args) in C:\Documents and Settings\simonjef\My Documents\Visual Studio 2008\Projects\Compiling\Compiling\Program.cs:line 42 
     at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) 
     at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
     at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
     at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
     at System.Threading.ThreadHelper.ThreadStart() 
    InnerException: 
+0

为什么要将源代码拆分为多个字符串? – MiMo 2012-04-25 11:44:15

+0

花了将近90到100毫秒来编译和执行我的机器上的方法。如果您尝试在现有代码执行中动态推送功能,则还可以使用MEF。比使用核心反射和编译器过程更好的选择。 – Jsinh 2012-04-25 12:46:59

+0

[在运行时动态生成DLL程序集]的可能的副本(http://stackoverflow.com/questions/604501/generating-dll-assembly-dynamically-at-run-time) – 2013-05-10 12:22:01

回答

4

我认为这就是问题所在:

string content = File.ReadAllText(@"D:\hi.cs"); 
string[] code = new string[content.Length]; 
char[] seperators = { '\n','\r','\t' }; 
code = content.Split(seperators); 

的想法(我相信)是CompileAssemblyFromSource不采取个别线路 - 数组中的每个字符串意味着是一个完整的C#源文件。所以,你可能只是需要

string[] code = new[] { File.ReadAllText(@"D:\hi.cs") }; 

请注意,即使你的第一块在做什么,你还是会一直在创造无缘无故的字符串数组正确的事情 - 这本来是简单的把它写作为:

string content = File.ReadAllText(@"D:\hi.cs"); 
char[] seperators = { '\n','\r','\t' }; 
string[] code = content.Split(seperators); 
+0

非常感谢。 – Tom 2012-04-25 12:14:14

1

你不需要将你的代码拆分成一个这样的数组。

该数组用于传递多个源文件。

+0

明白了。感谢您的信息。 – Tom 2012-04-25 12:14:47