2012-05-18 7 views
9

W tej chwili pracuję nad projektem, a zespół chce mieć sposób na napisanie kodu i edycję bez ponownej kompilacji całego projektu, dlatego postanowiłem spróbować zaimplementować silnik skryptowy .Odwołanie do bieżącego zestawu za pomocą CompilerParameters

Po wdrożeniu Lua w C++ wcześniej nie byłam nowicjuszem przy wdrażaniu skryptów w projektach. Chcieliśmy jednak wypróbować i zaimplementować proste C# przy użyciu przestrzeni nazw Microsoft.CSharp, w połączeniu z System.Reflection, który był już wbudowany w C#.

Tak więc, słysząc o tym, zacząłem pisać w dokumentach i wymyśliłem prototyp, który działa ALMOST - ale nie do końca.

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

namespace Scripting 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      StringBuilder builder = new StringBuilder(); 
      builder.Append("using System;"); 
      builder.Append("using Scripting;"); 
      builder.Append("class MyScript : IScript"); 
      builder.Append("{"); 
      builder.Append(" string ScriptName"); 
      builder.Append(" {"); 
      builder.Append("  get { return \"My Script\"; }"); 
      builder.Append(" }"); 

      builder.Append(" public bool Initialize()"); 
      builder.Append(" {"); 
      builder.Append("  Console.WriteLine(\"Hello, World!\");"); 
      builder.Append("  return true;"); 
      builder.Append(" }"); 
      builder.Append("}"); 

      CSharpCodeProvider provider = new CSharpCodeProvider(); 
      CompilerParameters param = new CompilerParameters(new string[] { "System.dll", "Scripting.dll" }); 
      param.GenerateInMemory = true; 
      param.GenerateExecutable = true; 
      CompilerResults result = provider.CompileAssemblyFromSource(param, builder.ToString()); 
      if (result.Errors.Count > 0) 
      { 
       foreach (CompilerError error in result.Errors) 
        Console.WriteLine(error); 
       Console.ReadKey(); 
       return; 
      } 
     } 
    } 
} 

Problem mam w tej chwili jest, że chcę, aby móc odwołać mój interfejs - IScript.cs (co jest wewnątrz przestrzeni nazw skryptów, a tym samym prąd montaż) - tak, że skrypty napisane i analizowany w kompilatorze może uzyskać do niego dostęp. Oczywiście, dodałem Scripting.dll jako parametr, ale wydaje się, że nie można uzyskać do niego dostępu z jakiegoś powodu. I am działa to w debugowaniu, więc może to być przyczyną poważnych mankamentów. Co robisz?

Czy istnieje sposób odniesienia do bieżącego złożenia i przekazanie go do CompilerParameters? Czy jestem naprawdę skrępowany/powinienem polegać na tworzeniu zespołu dla obiektów skryptowych/etc?

+0

Twój skrypt jest wszystko w jednej linii; rozważ wywołanie 'AppendLine()'. (nie żeby to miało jakikolwiek wpływ) – SLaks

Odpowiedz

5

Prawdopodobnie szuka w niewłaściwym katalogu.

Przekaż typeof(Program).Assembly.CodeBase, aby przekazać pełną ścieżkę.

0

można uzyskać plik wykonywalny i przekazać go do CompilerParameters:

 string exeName = Assembly.GetEntryAssembly().Location;  
     param.ReferencedAssemblies.Add(exeName);