Как я могу запустить код из строки?
У меня есть текстовое поле в моей программе. В текстовом поле вы можете написать имя функции / метода, который вы хотите запустить, а также передать параметры. Все это анализируется и через большой блок переключателей, если мой случай заполняется, код для этого конкретного случая, а также передача параметров.
Но я действительно хочу использовать 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 с помощью компилятора - вам понадобится тот же самый "текст" при вводе.