2016-04-12 2 views
2


Я пытаюсь скомпилировать код во время выполнения на C#, а затем из скомпилированного кода вызывать функцию или инициализировать класс, определенный в исходном коде.
Кода я в настоящее время:(C#) Класс компиляции во время выполнения и методы вызова из исходного кода

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 ><"); 
     } 
    } 
} 

Теперь Запуск выполнения загружено методом «Main» является успехом, и сообщение «Привет мир» печатается. Проблема начинается здесь: в исходном коде у меня есть метод под названием «SayHello». Я хочу вызвать этот метод из загруженного кода во время выполнения.
Если я раскомментировать метод «DoTurn», ошибка компиляции будет отображаться во время выполнения:

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



Мой вопрос - возможно ли это, и как?

Включение загруженного кода во время выполнения в одно и то же пространство имен не помогает (и это имеет смысл), так что это правильный способ сделать это?

Спасибо.

+2

Вы должны добавить ссылку на сборку. – SLaks

+1

Рассмотрите возможность использования Roslyn. – SLaks

+0

Возможно, вам стоит подумать о том, как вообще компилировать ваш код, прежде чем пытаться его динамически компилировать. –

ответ

4

Добавление ссылки на текущую сборку решить эту проблему:

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); 

Подробнее о: Compiling c# at runtime with user defined functions