它可在 AppDomain 間自由穿梭,故需繼承 System.MarshalByRefObject 抽象類別。若不繼承,在不同 AppDomain 傳遞物件時必會報錯(跨域傳遞的物件必須可序列化)。以 RemoteLoader 做為代理呼叫待執行的 .NET 程式。
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Text;
/// <summary> The Remote loader. </summary>
public class RemoteLoader : MarshalByRefObject
{
private Assembly assembly = null;
private String output = String.Empty;
public String Output { get { return this.output; } }
/// <summary> 呼叫目標方法 </summary>
public void InvokeMethod(String fullName, String className, String argsInput, String programName)
{
this.assembly = null; this.output = String.Empty;
try
{
this.assembly = Assembly.LoadFrom(fullName);
Type pgmType = null;
if (this.assembly != null) pgmType = this.assembly.GetType(className, true, true);
else pgmType = Type.GetType(className, true, true);
Object[] args = RunJob.GetArgs(argsInput);
BindingFlags defaultBinding = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.InvokeMethod | BindingFlags.Static;
CultureInfo cultureInfo = new CultureInfo("es-ES", false);
try
{
MethodInfo methisInfo = RunJob.GetItsMethodInfo(pgmType, defaultBinding, programName);
if (methisInfo == null) { this.output = "EMethod does not exist!"; }
if (methisInfo.IsStatic)
{
if (methisInfo.GetParameters().Length == 0)
{
if (methisInfo.ReturnType == typeof(void)) { pgmType.InvokeMember(programName, defaultBinding, null, null, null, cultureInfo); this.output = "STo call a method without return value successful."; }
else { this.output = (String)pgmType.InvokeMember(programName, defaultBinding, null, null, null, cultureInfo); }
}
else
{
if (methisInfo.ReturnType == typeof(void)) { pgmType.InvokeMember(programName, defaultBinding, null, null, args, cultureInfo); this.output = "STo call a method without return value successful."; }
else { this.output = (String)pgmType.InvokeMember(programName, defaultBinding, null, null, args, cultureInfo); }
}
}
else
{
if (methisInfo.GetParameters().Length == 0)
{
object pgmClass = Activator.CreateInstance(pgmType);
if (methisInfo.ReturnType == typeof(void)) { pgmType.InvokeMember(programName, defaultBinding, null, pgmClass, null, cultureInfo); this.output = "STo call a method without return value successful."; }
else { this.output = (String)pgmType.InvokeMember(programName, defaultBinding, null, pgmClass, null, cultureInfo); }
}
else
{
object pgmClass = Activator.CreateInstance(pgmType);
if (methisInfo.ReturnType == typeof(void)) { pgmType.InvokeMember(programName, defaultBinding, null, pgmClass, args, cultureInfo); this.output = "STo call a method without return value successful."; }
else { this.output = (String)pgmType.InvokeMember(programName, defaultBinding, null, pgmClass, args, cultureInfo); }
}
}
}
catch { this.output = (String)pgmType.InvokeMember(programName, defaultBinding, null, null, null, cultureInfo); }
}
catch (Exception e) { this.output = "E" + e.Message; }
}
}
InvokeMethod 方法只需提供組件全名、類別全名、待執行方法的輸入參數與全名即可執行,支援帶參數/不帶參數、靜態/非靜態方法。
AssemblyDynamicLoader loader = new AssemblyDynamicLoader();
String output = loader.InvokeMethod("fileName", "ymtcla", "yjoinp", "ymtpgm");
loader.Unload();