Problem mit .NET Scripting

lordfritte

Erfahrenes Mitglied
Hallo ich befasse mich zur Zeit mit .NET Scripting und bin schon auf ein Problem gestoßen,
Ich möchte in meinem Programm eine Zeile in meiner Anwendung als Script ausführen.
In meinee Scriptzeile möchte ich ein Objekt(ScriptElements) über eine Variable x nutzen,
hier mein Code:
PHP:
namespace Scripting
{
  public class ScriptingSample
  {
    public void Main(string[] args)
    {
      string sScriptLine = "x.Date();";

      ScriptElements elements = new ScriptElements();
      ScriptManager manager = new ScriptManager();

      Console.WriteLine(manager.RunScript(elements, sScriptLine));

      Console.ReadKey();
    }

  }

  #region ScriptManager

  public class ScriptManager
  {
    List<string> arrList = new List<string>();
    public delegate string ScriptRun(ScriptElements x);
    public ScriptRun runDelegate;

    public ScriptManager()
    {
      arrList.Clear();
      arrList.Add("System.dll");
      arrList.Add("System.Windows.Forms.dll");
    }

    public string RunScript(ScriptElements x, string sScriptLine)
    {
      string sRes = "";

      CodeCompileUnit compileUnit = new CodeCompileUnit();
      CodeNamespace nameSpace = new CodeNamespace("Scripting");
      CodeTypeDeclaration reletionClass = new CodeTypeDeclaration("ScriptClass");
      CodeMemberMethod calculationFunction = new CodeMemberMethod();
      CompilerResults compilerResults = null;
      object objFunc;

      compileUnit.Namespaces.Add(nameSpace);
      compileUnit.ReferencedAssemblies.AddRange(arrList.ToArray());
      nameSpace.Imports.Add(new CodeNamespaceImport("System"));
      nameSpace.Imports.Add(new CodeNamespaceImport("System.Windows.Forms"));
      nameSpace.Types.Add(reletionClass);
      reletionClass.IsClass = true;
      reletionClass.TypeAttributes = System.Reflection.TypeAttributes.Public;
      reletionClass.Members.Add(calculationFunction);
      calculationFunction.Attributes = MemberAttributes.Public;
      calculationFunction.ReturnType = new CodeTypeReference(typeof(string));
      calculationFunction.Name = "Run";
      calculationFunction.Parameters.Add(new CodeParameterDeclarationExpression(typeof(ScriptElements), "x"));
      calculationFunction.Statements.Add(new CodeMethodReturnStatement(new CodeSnippetExpression(sScriptLine)));

      CompilerParameters compilerParameters = new CompilerParameters();
      compilerParameters.GenerateInMemory = true;

      CSharpCodeProvider csharp = new CSharpCodeProvider();
      compilerResults = csharp.CompileAssemblyFromDom(compilerParameters, compileUnit);

      if ((compilerResults != null) && (compilerResults.Errors.Count > 0))
      {
        for (int i = 0; i < compilerResults.Errors.Count; i++)
        {
          MessageBox.Show(compilerResults.Errors[i].ToString());
        }
      }
      else
      {
        objFunc = compilerResults.CompiledAssembly.CreateInstance("Scripting.ScriptClass", true);
        runDelegate = (ScriptRun)Delegate.CreateDelegate(typeof(ScriptRun), objFunc, calculationFunction.Name);

        if (runDelegate != null)
          sRes = runDelegate(x);
      }

      return sRes;
    }
  }

  #endregion

  #region ScriptElements

  public class ScriptElements
  {
    public ScriptElements()
    { }

    public string Date()
    {
      return DateTime.Now.ToString();
    }
  }

  #endregion
}

Mein Problem ist nun ganz einfach, wenn ich das laufen lasse bekomme ich über die MessageBox folgenden Fehler:
Der Typ- oder namespacename ScriptElements ist im Namespace Scripting nicht vorhanden. (Fehlt eine Assemblyverweis?).
Wie bekomme ich das ganze zum laufen?
Wenn ich ScriptElements durch z.b. float ersetze, zum rechnen, läuft es wunderbar.
 
Hi

Du fügst der zur kompilierende Anwendung keine Referenz hinzu, die die Deklaration von ScriptElements enthält. Du müsstest sozusagen diese Anwendung als Referenz mit eintragen.
 
Hallo, danke für den Tip, also hier mit geht es jetzt:
PHP:
List<string> assemblyNames = new List<string>();
      foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
      {
        if((asm.Location != null) && (asm.Location.Length > 0))
          assemblyNames.Add(new Uri(asm.Location).LocalPath);
      }
      compileUnit.ReferencedAssemblies.AddRange(assemblyNames.ToArray());
 
Es läuft aber nicht, ich bekomme immer in der Zeile: "runDelegate = (ScriptRun)Delegate.CreateDelegate(typeof(ScriptRun), objFunc, calculationFunction.Name);" Die Exception:
[System.ArgumentException] = {"Fehler beim Binden an die Zielmethode."}
 
Zuletzt bearbeitet:
Zurück