2、創 建RemoteLoader類,它可以在AppDomain中自由穿越,這就需要繼承System.MarshalByRefObject這個抽象類,這裡RemoteLoader如果不繼承 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
{
/// <summary>
/// The assembly we need.
/// </summary>
private Assembly assembly = null;
/// <summary>
/// The output.
/// </summary>
private String output = String.Empty;
/// <summary>
/// Gets the output.
/// </summary>
/// <value>The output.</value>
public String Output
{
get
{
return this.output;
}
}
/// <summary>
/// Invokes the method.
/// </summary>
/// <param name="fullName">The full name.</param>
/// <param name="className">Name of the class.</param>
/// <param name="argsInput">The args input.</param>
/// <param name="programName">Name of the program.</param>
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); //'ymtpgm' is program's name and the return value of it must be started with 'O'.
}
}
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); //'ymtpgm' is program's name and the return value of it must be started with 'O'.
}
}
}
}
catch
{
this.output = (String)pgmType.InvokeMember(programName, defaultBinding, null, null, null, cultureInfo);
}
}
catch (Exception e)
{
this.output = "E" + e.Message;
}
}
}
其中的InvokeMethod方法只要提供Assembly的全名 、類的全名、待執行方法的輸入參數和其全名就可以執行該方法,該方法可以是帶參數或不帶參數,靜態的或者不是靜態的。
最後這樣 使用這兩個類:
AssemblyDynamicLoader loader = new AssemblyDynamicLoader();
String output = loader.InvokeMethod("fileName", "ymtcla", "yjoinp", "ymtpgm");
loader.Unload();