2012-05-18 10 views
9

Ahora estoy trabajando en un proyecto, y el equipo quiere una forma de escribir código y editarlo sin tener que volver a compilar todo el proyecto, así que he decidido probar e implementar un motor de scripting .Hace referencia al ensamblado actual con CompilerParameters

Después de haber implementado Lua en C++ antes, no era un novato completo para implementar capacidades de scripting en los proyectos. Sin embargo, queríamos intentar implementar C# directo utilizando el espacio de nombres Microsoft.CSharp, combinado con System.Reflection que ya estaba integrado en C#.

Así que, habiéndome enterado de esto, hurgué en los documentos y he descubierto un prototipo que CASI funciona, pero que no funciona del todo.

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

El problema que tengo en este momento es que yo quiero ser capaz de hacer referencia a mi interfaz - IScript.cs (que está dentro del espacio de nombres de secuencias de comandos y, por tanto, el conjunto actual) - para que los scripts escritos y analizan en el compilador puede acceder a él. Obviamente, agregué Scripting.dll como parámetro, pero parece que no se puede acceder por alguna razón u otra. I am ejecutándolo en depuración así que esto podría ser causa de algunos daños importantes en la cara. ¿Qué hacer?

¿Hay alguna manera de hacer referencia al ensamblaje actual y pasarlo a CompilerParameters? ¿O estoy realmente jodido/debería confiar en crear un ensamblaje para objetos de guiones/etc.?

+0

Su guión es de una sola línea; considere llamar a 'AppendLine()'. (No es que haga ninguna diferencia) – SLaks

Respuesta

5

Probablemente esté buscando en el directorio incorrecto.

Pase typeof(Program).Assembly.CodeBase para pasar la ruta completa.

0

Usted puede obtener el ejecutable y pasarlo a los CompilerParameters:

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