โดยส่วนตัวฉันใช้ C # เป็นภาษาสคริปต์ NET framework (และ Mono ขอบคุณ Matthew Scharley) รวมคอมไพเลอร์สำหรับภาษา. NET แต่ละภาษาไว้ในเฟรมเวิร์กด้วย
โดยทั่วไปมี 2 ส่วนในการใช้งานระบบนี้
อนุญาตให้ผู้ใช้คอมไพล์โค้ดสิ่งนี้ค่อนข้างง่ายและสามารถทำได้โดยใช้โค้ดเพียงไม่กี่บรรทัด (แม้ว่าคุณอาจต้องการเพิ่มกล่องโต้ตอบข้อผิดพลาดซึ่งอาจเป็นโค้ดอีกสองสามบรรทัดขึ้นอยู่กับวิธีการใช้งาน คุณต้องการให้เป็น)
สร้างและใช้คลาสที่มีอยู่ในแอสเซมบลีที่คอมไพล์แล้วซึ่งยากกว่าขั้นตอนก่อนหน้าเล็กน้อย (ต้องใช้การไตร่ตรองเล็กน้อย) โดยพื้นฐานแล้วคุณควรปฏิบัติต่อแอสเซมบลีที่คอมไพล์แล้วเป็น "ปลั๊กอิน" สำหรับโปรแกรม มีบทเรียนไม่กี่วิธีในการสร้างระบบปลั๊กอินใน C # (Google คือเพื่อนของคุณ)
ฉันได้ติดตั้งแอปพลิเคชัน "ด่วน" เพื่อสาธิตวิธีการใช้งานระบบนี้ (รวมถึงสคริปต์การทำงาน 2 สคริปต์!) นี่คือรหัสที่สมบูรณ์สำหรับแอปพลิเคชันเพียงสร้างรหัสใหม่และวางรหัสในไฟล์ "program.cs" ณ จุดนี้ฉันต้องขอโทษสำหรับโค้ดจำนวนมากที่ฉันกำลังจะวาง (ฉันไม่ได้ตั้งใจให้มันมีขนาดใหญ่ขนาดนี้ แต่มันถูกลบเลือนไปเล็กน้อยกับการแสดงความคิดเห็นของฉัน)
using System;
using System.Windows.Forms;
using System.Reflection;
using System.CodeDom.Compiler;
namespace ScriptingInterface
{
public interface IScriptType1
{
string RunScript(int value);
}
}
namespace ScriptingExample
{
static class Program
{
[STAThread]
static void Main()
{
Assembly compiledScript = CompileCode(
"namespace SimpleScripts" +
"{" +
" public class MyScriptMul5 : ScriptingInterface.IScriptType1" +
" {" +
" public string RunScript(int value)" +
" {" +
" return this.ToString() + \" just ran! Result: \" + (value*5).ToString();" +
" }" +
" }" +
" public class MyScriptNegate : ScriptingInterface.IScriptType1" +
" {" +
" public string RunScript(int value)" +
" {" +
" return this.ToString() + \" just ran! Result: \" + (-value).ToString();" +
" }" +
" }" +
"}");
if (compiledScript != null)
{
RunScript(compiledScript);
}
}
static Assembly CompileCode(string code)
{
Microsoft.CSharp.CSharpCodeProvider csProvider = new Microsoft.CSharp.CSharpCodeProvider();
CompilerParameters options = new CompilerParameters();
options.GenerateExecutable = false;
options.GenerateInMemory = true;
options.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
CompilerResults result;
result = csProvider.CompileAssemblyFromSource(options, code);
if (result.Errors.HasErrors)
{
return null;
}
if (result.Errors.HasWarnings)
{
}
return result.CompiledAssembly;
}
static void RunScript(Assembly script)
{
foreach (Type type in script.GetExportedTypes())
{
foreach (Type iface in type.GetInterfaces())
{
if (iface == typeof(ScriptingInterface.IScriptType1))
{
ConstructorInfo constructor = type.GetConstructor(System.Type.EmptyTypes);
if (constructor != null && constructor.IsPublic)
{
ScriptingInterface.IScriptType1 scriptObject = constructor.Invoke(null) as ScriptingInterface.IScriptType1;
if (scriptObject != null)
{
MessageBox.Show(scriptObject.RunScript(50));
}
else
{
}
}
else
{
}
}
}
}
}
}
}