我使用 .NET 集成的 C# 编译器完成了这个“脚本”操作。
这是一些工作要做,但基本上看起来像这样:
public Assembly Compile(string[] source, string[] references) {
CodeDomProvider provider = new CSharpCodeProvider();
CompilerParameters cp = new CompilerParameters(references);
cp.GenerateExecutable = false;
cp.GenerateInMemory = true;
cp.TreatWarningsAsErrors = false;
try {
CompilerResults res = provider.CompileAssemblyFromSource(cp, source);
// ...
return res.Errors.Count == 0 ? res.CompiledAssembly : null;
}
catch (Exception ex) {
// ...
return null;
}
}
public object Execute(Assembly a, string className, string methodName) {
Type t = a.GetType(className);
if (t == null) throw new Exception("Type not found!");
MethodInfo method = t.GetMethod(methodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); // Get method
if (method == null) throw new Exception("Method '" + methodName + "' not found!"); // Method not found
object instance = Activator.CreateInstance(t, this);
object ret = method.Invoke(instance, null);
return ret;
}
真正的代码可以做更多的事情,包括代码编辑器。
它多年来在我们的工厂运行良好。
这样,用户使用 C# 编写脚本,因此可以使用与您相同的 API。
您可以使用看起来像普通.cs
文件的代码模板。它在运行时构建并提供source
给Compile
.
using System;
using System.IO;
using ...
namespace MyCompany.Stuff {
public class ScriptClass {
public object main() {
// copy user code here
// call your own methods here
}
// or copy user code here
private int test(int x) { /* ... */ }
}
}
例子:
string[] source = ??? // some code from TextBoxes, files or whatever, build with template file...
string[] references = new string[] { "A.dll", "B.dll" };
Assembly a = Compile(source, references);
object result = Execute(a, "MyCompany.Stuff.ScriptClass", "main");