2012-05-18 5 views
9

Momentan arbeite ich an einem Projekt, und das Team möchte Code schreiben und bearbeiten, ohne das gesamte Projekt neu kompilieren zu müssen. Daher habe ich beschlossen, eine Scripting Engine zu implementieren .Die aktuelle Assembly mit CompilerParametern referenzieren

Nach der Implementierung von Lua in C++ war ich noch kein Neuling für die Implementierung von Skriptfunktionen in Projekten. Wir wollten jedoch versuchen, direktes C# mithilfe des Namespaces Microsoft.CSharp in Kombination mit System.Reflection, das bereits in C# integriert war, zu implementieren.

Nachdem ich davon gehört habe, habe ich in Docs herumgestöbert und ich habe mir einen Prototyp ausgedacht, der FAST funktioniert - aber nicht ganz.

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

Die Frage, die ich im Moment habe, ist, dass ich meine Schnittstelle verweisen können, will - IScript.cs (die innerhalb des Scripting-Namespace ist und somit die aktuelle Assembly) - so dass Skripte geschrieben und analysiert im Compiler kann darauf zugreifen. Offensichtlich habe ich Scripting.dll als Parameter hinzugefügt, aber es scheint nicht möglich zu sein, aus irgendeinem Grund darauf zuzugreifen. I am läuft es in debug so könnte dies Ursache für einige große facepalmage sein. Was soll?

Gibt es eine Möglichkeit, die aktuelle Assembly zu referenzieren und an CompilerParameters zu übergeben? Oder bin ich königlich verwirrt/sollte ich mich darauf verlassen, eine Assembly für Skriptobjekte/etc zu erstellen?

+0

Ihr Skript ist alles auf einer Linie; erwäge den Aufruf von 'AppendLine()'. (Nicht, dass es einen Unterschied machen würde) – SLaks

Antwort

5

Es ist wahrscheinlich in das falsche Verzeichnis suchen.

Übergeben Sie typeof(Program).Assembly.CodeBase, um den vollständigen Pfad zu übergeben.

0

Sie können die ausführbare Datei erhalten und sie den Compiler passieren:

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