Как я могу запустить код из строки?

У меня есть текстовое поле в моей программе. В текстовом поле вы можете написать имя функции / метода, который вы хотите запустить, а также передать параметры. Все это анализируется и через большой блок переключателей, если мой случай заполняется, код для этого конкретного случая, а также передача параметров.

Но я действительно хочу использовать stringbuilder для создания исходного кода, а затем запустить его!

Это пример исходного кода, созданного с помощью моего stringbuilder.

 outlook outlooken = new outlook(appNwindow);

а также

  outlooken.createNewEmail(scriptarray[i][1],scriptarray[i][2],
  scriptarray[i][3],scriptarray[i][4]);

Использование stringbuilder для создания строк вообще не проблема. Но как мне их запустить?

Я много тестировал, и мне все удалось, но я думаю, что чего-то не хватает, потому что мой код всегда выдает ошибку...

Вот мой код соучастия

 CodeDomProvider myCodeDomeProvider = CodeDomProvider.CreateProvider("CSharp");
 String [] referenceAssemblies = {"System.dll"};
 //  string myAssemblyName = "myAssembly.dll";
 CompilerParameters myCompilerparameters = 
 new CompilerParameters(referenceAssemblies);

        myCompilerparameters.GenerateExecutable = false;
        myCompilerparameters.GenerateInMemory = true;

  //*** Here's the sourcecode it want to compile
  string[] arr1 = new string[] { "outlook outlooken = new outlook(appNwindow);","outlooken.createNewEmail(scriptarray[i][1],scriptarray[i][2],scriptarray[i[3],scriptarray[i][4]);"};

        CompilerResults myResults = myCodeDomeProvider.CompileAssemblyFromSource(myCompilerparameters, arr1);
        string objectname = "testet";
        string method = "createNewEmail";
        object[] args = new object[2];

        args[0] = "to";
        args[1] = "CC";

        if (myResults.Errors.HasErrors)

         {
            StringBuilder errors = new StringBuilder("Compiler Errors :\r\n");
            foreach (CompilerError error in myResults.Errors)
            {
            errors.AppendFormat("Line {0},{1}\t: {2}\n",
            error.Line, error.Column, error.ErrorText);
            }

            throw new Exception(errors.ToString());
            }
            else
            {
            Assembly assem = myResults.CompiledAssembly;
            object instance = null;

            Type type = assem.GetType(objectname);
            MethodInfo miChk = type.GetMethod(method);

            if (!miChk.IsStatic)
            {
            instance = assem.CreateInstance(objectname);
            type = instance.GetType();
            }

            MethodInfo mi = type.GetMethod(method);

            mi.Invoke(instance, args);
            }

Вот ошибки, которые я получаю при запуске:

Дополнительная информация: Ошибки компилятора:

Строка 1,1: пространство имен не может напрямую содержать элементы, такие как поля или методы

Строка 1,25: ожидаемый класс, делегат, перечисление, интерфейс или структура

Строка 1,1: пространство имен не может напрямую содержать элементы, такие как поля или методы

Строка 1,41: ожидаемый идентификатор

Строка 1,59: ожидается идентификатор

Строка 1,77: ожидается идентификатор

Строка 1,95: ожидается идентификатор

1 ответ

Решение

CodeDom не будет компилировать и выполнять произвольные инструкции. Код, который вы компилируете, должен быть действительным кодом C#, как если бы вы делали файл C# из исходного кода.

Это означает, что вам нужно обернуть оператор в пространство имен + класс и поместить его в метод (может быть статическим) в классе.

По сути, думайте о вводе так, как будто вы пишете обычный файл C# и компилируете файл.cs с помощью компилятора - вам понадобится тот же самый "текст" при вводе.

Другие вопросы по тегам