2016-04-12 6 views
2


Ich versuche, Code zur Laufzeit in C# zu kompilieren, dann vom kompilierten Code eine Funktion aufzurufen oder eine Klasse zu initialisieren, die im ursprünglichen Code definiert ist. Ich habe
Der Code zur Zeit:(C#) Klasse zur Laufzeit kompilieren und Methoden vom ursprünglichen Code aufrufen

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Microsoft.CSharp; 
using System.CodeDom.Compiler; 
using System.Reflection; 

namespace CTFGame 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string code = @" 

using System; 

namespace CTFGame 
{ 
    public class MyPlayer 
    { 
     public static void Main() 
     { 
      Console.WriteLine(""Hello world""); 
     } 
     /*public void DoTurn() 
     { 
      Program.SayHello(); 
     }*/ 
    } 
} 

"; 
      CSharpCodeProvider provider = new CSharpCodeProvider(); 
      CompilerParameters parameters = new CompilerParameters(); 
      parameters.GenerateInMemory = true; 

      CompilerResults results = provider.CompileAssemblyFromSource(parameters, code); 
      if (results.Errors.HasErrors) 
      { 
       string errors = ""; 
       foreach (CompilerError error in results.Errors) 
       { 
        errors += string.Format("Error #{0}: {1}\n", error.ErrorNumber, error.ErrorText); 
       } 
       Console.Write(errors); 
      } 
      else 
      { 
       Assembly assembly = results.CompiledAssembly; 
       Type program = assembly.GetType("CTFGame.MyPlayer"); 
       MethodInfo main = program.GetMethod("Main"); 
       main.Invoke(null, null); 
      } 
     } 

     public static void SayHello() 
     { 
      Console.WriteLine("I'm awesome ><"); 
     } 
    } 
} 

Jetzt Ausführen der Laufzeit geladen Methode ‚Main‘ ist ein Erfolg, und die Meldung „Hallo Welt“ gedruckt wird. Das Problem beginnt hier: Im ursprünglichen Code habe ich eine Methode namens "SayHello". Ich möchte diese Methode von meinem Laufzeit-geladenen Code aufrufen.
Wenn ich die "DoTurn" Methode Kommentar-, wird ein Compiler-Fehler im laufenden Betrieb zeigen:

Error #CS0103: The name 'Program' does not exist in the current context 



Meine Frage ist - ist das möglich, und wie?

Das Einfügen des Laufzeit-geladenen Codes in denselben Namespace hilft nicht (und das ist sinnvoll). Was ist also der richtige Weg?

Danke.

+2

Sie müssen einen Verweis auf die Assembly hinzuzufügen. – SLaks

+1

Verwenden Sie Roslyn. – SLaks

+0

Vielleicht sollten Sie darüber nachdenken, Ihren Code überhaupt kompilieren zu lassen, bevor Sie versuchen, ihn dynamisch zu kompilieren. –

Antwort

4

einen Verweis auf die aktuelle Assembly Hinzufügen löste das Problem:

CSharpCodeProvider provider = new CSharpCodeProvider(); 
CompilerParameters parameters = new CompilerParameters(); 
parameters.GenerateInMemory = true;     
//The next line is the addition to the original code 
parameters.ReferencedAssemblies.Add(Assembly.GetEntryAssembly().Location); 

Mehr über: Compiling c# at runtime with user defined functions

Verwandte Themen