この「スクリプト」は、.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");