using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;
namespace ScriptRunnerLibrary
{
public class NoExecutableAssemblyError: Exception { };
public class NoSuchClassNameError: Exception { };
public class NoSuchClassFunctionError: Exception { };
///
/// コンパイル済みスクリプトを表すクラス
/// 別 AppDomain で動作させることを前提に MarshalByRefObject を継承している。
///
public class Script: MarshalByRefObject
{
CompilerResults compilerResults = null;
///
/// デフォルトのアセンブリ参照を使ってスクリプトをコンパイルする
///
/// Compile(script,
/// new string[]{
/// "System.dll",
/// "System.Data.dll",
/// "System.Deployment.dll",
/// "System.Drawing.dll",
/// "System.Windows.Forms.dll",
/// "System.Xml.dll",
/// "mscorlib.dll"
/// });
///
/// と同等の動作。
///
/// スクリプトソース
/// 成功したら true
public bool Compile(string script)
{
return Compile(script,
new string[]{
"System.dll",
"System.Data.dll",
"System.Deployment.dll",
"System.Drawing.dll",
"System.Windows.Forms.dll",
"System.Xml.dll",
"mscorlib.dll"
});
}
///
/// アセンブリ参照名を指定してスクリプトをコンパイルする
///
/// スクリプトソース
///
/// アセンブリ参照名
///
/// new string[]{"System.dll", "System.Windows.Forms.dll"}
/// のようにして与える。
///
/// 成功したら true
public bool Compile(string script, string[] assemblyNames)
{
// コンパイル時のオプション設定
CompilerParameters param = new CompilerParameters(assemblyNames);
param.GenerateInMemory = true; // exe を作らない
param.IncludeDebugInformation = false; // デバッグ情報を付加しない
// コンパイルする
CSharpCodeProvider codeProvider = new CSharpCodeProvider();
compilerResults = codeProvider.CompileAssemblyFromSource(param, script);
// エラーメッセージが無ければ成功
return compilerResults.Errors.Count == 0;
}
///
/// 直前のコンパイルで生じたエラーメッセージを返す。
///
/// エラーメッセージ
public String[] ErrorMessage()
{
if (compilerResults == null)
return new string[] { };
string[] result = new string[compilerResults.Errors.Count];
for (int i = 0; i < compilerResults.Errors.Count; i++)
result[i]= compilerResults.Errors[i].ErrorText;
return result;
}
private Type getClassReference(string ClassName)
{
if (compilerResults == null ||
compilerResults.CompiledAssembly == null)
throw new NoExecutableAssemblyError();
return compilerResults.CompiledAssembly.GetType(ClassName);
}
///
/// クラス関数を呼び出す。
///
/// クラス名
/// クラス関数名
/// パラメータ
///
public object InvokeClassFunction(string ClassName, string FunctionName, object[] Parameters)
{
// 渡された引数の型をチェック
Type[] argumentTypes = new Type[Parameters.Length];
for (int i = 0; i < Parameters.Length; i++)
argumentTypes[i] = Parameters[i].GetType();
// クラスリファレンスを取得
Type type = getClassReference(ClassName);
if (type == null)
throw new NoSuchClassNameError();
// クラス関数を取得
MethodInfo mi= type.GetMethod(FunctionName, argumentTypes);
if (mi == null)
throw new NoSuchClassFunctionError();
// 呼び出し
return mi.Invoke(null, Parameters);
}
///
/// クラスのインスタンスを作成する。
///
/// クラス名
/// コンストラクタに渡すパラメータ
/// クラスのインスタンス
public object CreateInstance(string ClassName, object[] Parameters)
{
// 渡された引数の型をチェック
Type[] argumentTypes = new Type[Parameters.Length];
for (int i = 0; i < Parameters.Length; i++)
argumentTypes[i] = Parameters[i].GetType();
// クラスリファレンスを取得
Type type = getClassReference(ClassName);
if (type == null)
throw new NoSuchClassNameError();
// コンストラクタの取得
ConstructorInfo constructorInfo = type.GetConstructor(argumentTypes);
if (constructorInfo == null)
throw new NoSuchClassFunctionError();
// 呼び出し
return constructorInfo.Invoke(Parameters);
}
///
/// オブジェクトのメンバ関数を呼びだす。
///
/// 対象となるオブジェクト
/// 関数名
/// パラメータ
///
public object InvokeFunction(object Object, string FunctionName, object[] Parameters)
{
// 渡された引数の型をチェック
Type[] argumentTypes = new Type[Parameters.Length];
for (int i = 0; i < Parameters.Length; i++)
argumentTypes[i] = Parameters[i].GetType();
// 型情報を取得
Type type = Object.GetType();
// メンバ関数の取得
MethodInfo methodInfo = type.GetMethod(FunctionName, argumentTypes);
if (methodInfo == null)
throw new NoSuchClassFunctionError();
// 呼び出し
return methodInfo.Invoke(Object, Parameters);
}
///
/// オブジェクトのフィールドに値を代入する
///
/// 対象となるオブジェクト
/// フィールド名
/// 値
public void SetField(object Object, string FieldName, object Value)
{
Type type = Object.GetType();
FieldInfo fieldInfo = type.GetField(FieldName);
fieldInfo.SetValue(Object, Value);
}
///
/// オブジェクトのフィールドから値を読み出す
///
/// 対象となるオブジェクト
/// フィールド名
/// 値
public object GetField(object Object, string FieldName)
{
Type type = Object.GetType();
FieldInfo fieldInfo = type.GetField(FieldName);
return fieldInfo.GetValue(Object);
}
///
/// オブジェクトのプロパティに値を代入する
///
/// 対象となるオブジェクト
/// プロパティ名
/// 値
public void SetProperty(object Object, string PropertyName, object Value)
{
Type type = Object.GetType();
PropertyInfo propertyInfo = type.GetProperty(PropertyName);
propertyInfo.SetValue(Object, Value, null);
}
///
/// オブジェクトのプロパティから値を読み出す
///
/// 対象となるオブジェクト
/// プロパティ名
/// 値
public object GetProperty(object Object, string PropertyName)
{
Type type = Object.GetType();
PropertyInfo propertyInfo = type.GetProperty(PropertyName);
return propertyInfo.GetValue(Object, null);
}
}
}