C# 如何从字符串运行代码?
我的程序中有一个文本框。在文本框中,您可以写入要运行的函数/方法的名称以及传递参数。这是所有解析,并通过一个大的开关块,如果我的情况是填补我的代码为特定的情况下,以及传递参数 但我真正想做的是使用stringbuilder构建源代码,然后运行它强> 这是使用我的stringbuilder构建的源代码示例C# 如何从字符串运行代码?,c#,dynamic-code,C#,Dynamic Code,我的程序中有一个文本框。在文本框中,您可以写入要运行的函数/方法的名称以及传递参数。这是所有解析,并通过一个大的开关块,如果我的情况是填补我的代码为特定的情况下,以及传递参数 但我真正想做的是使用stringbuilder构建源代码,然后运行它 这是使用我的stringbuilder构建的源代码示例 outlook outlooken = new outlook(appNwindow); 及 使用stringbuilder创建字符串完全没有问题。但我该如何管理它们呢 我已经做了很多测试,并设
outlook outlooken = new outlook(appNwindow);
及
使用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行:预期标识符CodeDom不会编译和执行任意语句。您编译的代码必须是有效的C代码,就像您从源代码编写C文件一样 这意味着您需要将语句包装到名称空间+类中,并将其放入类中的方法(可以是静态的)中
基本上,将输入想象为编写一个普通的C#文件并使用编译器编译.cs文件——输入中需要相同的“文本”。CodeDom不会编译和执行任意语句。您编译的代码必须是有效的C代码,就像您从源代码编写C文件一样 这意味着您需要将语句包装到名称空间+类中,并将其放入类中的方法(可以是静态的)中
基本上,把输入想象成编写一个普通的C#文件,然后用编译器编译.cs文件——输入中需要相同的“文本”。。。。另外,“aswell”不是一个词。请记住,如果您这样做,那么在此编译的程序集将加载到当前AppDomain中,并且无法卸载。如果你一次又一次地这样做,你的内存就会泄漏。您真正需要做的是在另一个AppDomain或另一个进程中执行此操作。否则,您可以尝试使用DLR(可能是Iron Python)或创建自己的表达式树编译器。这不是小事,这不是.net的一个受良好支持的领域。。。。另外,“aswell”不是一个词。请记住,如果您这样做,那么在此编译的程序集将加载到当前AppDomain中,并且无法卸载。如果你一次又一次地这样做,你的内存就会泄漏。您真正需要做的是在另一个AppDomain或另一个进程中执行此操作。否则,您可以尝试使用DLR(可能是Iron Python)或创建自己的表达式树编译器。这不是小事,这不是.net的一个受良好支持的领域。
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);
}