using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.CSharp; using System.CodeDom.Compiler; using System.Reflection; namespace ScriptRunnerLibrary { /// /// DLLに格納された ScriptRunnerLibrary.Script クラスを /// 使って文字列として渡されたC#コードをコンパイルし、 /// 実行するためのクラス /// public class ScriptRunner { static Random rand = new Random(); AppDomain appDomain = null; ScriptRunnerLibrary.Script script = null; private void unloadLibrary() { // アプリケーション終了時に暗黙的に解放される // ことがあるため、エラー回避用に catch している if (appDomain != null) { try { AppDomain.Unload(appDomain); appDomain = null; } catch (CannotUnloadAppDomainException) { ; // すでにアンロードされていた } } } private void loadLibrary() { // ドメインには乱数を使って一意の名前を付ける string domainName = Convert.ToString(rand.Next(), 16) + Convert.ToString(rand.Next(), 16) + Convert.ToString(rand.Next(), 16) + Convert.ToString(rand.Next(), 16); appDomain = AppDomain.CreateDomain(domainName); script = (ScriptRunnerLibrary.Script) appDomain.CreateInstanceAndUnwrap( "ScriptRunner", "ScriptRunnerLibrary.Script"); } /// /// 与えられたアセンブリを参照しつつスクリプトをコンパイルする /// /// C#スクリプト /// 参照するアセンブリの名前リスト public ScriptRunner(string scriptSource, string[] assemblyNames) { loadLibrary(); script.Compile(scriptSource, assemblyNames); } ~ScriptRunner() { // メモリを開放する unloadLibrary(); } /// /// 標準のアセンブリを参照しつつスクリプトをコンパイルする /// /// C#スクリプト public ScriptRunner(string scriptSource) { loadLibrary(); script.Compile(scriptSource); } /// /// クラス関数を呼び出す /// /// クラス名 /// クラス関数名 /// クラス関数への引数 /// public object InvokeClassFunction(string ClassName, string FunctionName, object[] Parameters) { return script.InvokeClassFunction(ClassName, FunctionName, Parameters); } /// /// クラス名を指定してオブジェクトを作成する /// /// クラス名 /// コンストラクタへの引数 /// public object CreateInstance(string ClassName, object[] Parameters) { return script.CreateInstance(ClassName, Parameters); } /// /// オブジェクトのメンバ関数を呼び出す /// /// /// で作ったオブジェクト /// メンバ関数名 /// 関数への引数 /// public object InvokeFunction(object Object, string FunctionName, object[] Parameters) { return script.InvokeFunction(Object, FunctionName, Parameters); } /// /// オブジェクトのフィールドに値を代入する /// /// 対象となるオブジェクト /// フィールド名 /// 値 public void SetField(object Object, string FieldName, object Value) { script.SetField(Object, FieldName, Value); } /// /// オブジェクトのフィールドから値を読み出す /// /// 対象となるオブジェクト /// フィールド名 /// public object GetField(object Object, string FieldName) { return script.GetField(Object, FieldName); } /// /// オブジェクトのプロパティに値を代入する /// /// 対象となるオブジェクト /// プロパティ名 /// 値 public void SetProperty(object Object, string PropertyName, object Value) { script.SetProperty(Object, PropertyName, Value); } /// /// オブジェクトのプロパティから値を読み出す /// /// 対象となるオブジェクト /// プロパティ名 /// public object GetProperty(object Object, string PropertyName) { return script.GetProperty(Object, PropertyName); } } }