我编译了一个插件,然后在一个新的AppDomain中创建它的一个实例。然后我想在插件对象中执行一个方法但是会导致 ArgumentException :
"Object of type System.MarshalByRefObject can not be converted to type Data"
下面的代码应该是可编译的,并导致上述例外。要使其工作,您还必须签署程序集(项目 - >属性 - >签名 - >签署程序集 - >新...)
IPlugin.cs:
using System;
namespace Plugin
{
[Serializable]
class Data : MarshalByRefObject
{
int value;
}
interface IPlugin
{
void DoStuff(Data data);
}
}
的Program.cs:
using System;
using System.CodeDom.Compiler;
using System.IO;
using System.Security.Policy;
using System.Security;
using System.Security.Permissions;
using System.Reflection;
namespace Plugin
{
class Program
{
public class Sandbox : MarshalByRefObject
{
const string BaseDirectory = "Untrusted";
const string DomainName = "Sandbox";
private object instance;
public static Sandbox Create()
{
var setup = new AppDomainSetup()
{
ApplicationBase = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, BaseDirectory),
ApplicationName = DomainName,
DisallowBindingRedirects = true,
DisallowCodeDownload = true,
DisallowPublisherPolicy = true
};
Evidence ev = new Evidence();
ev.AddHostEvidence(new Zone(SecurityZone.Internet));
var permissions = new PermissionSet(PermissionState.None);
permissions.AddPermission(new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess));
permissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
StrongName fullTrustAssembly = typeof(Sandbox).Assembly.Evidence.GetHostEvidence<StrongName>();
var domain = AppDomain.CreateDomain(DomainName, null, setup, permissions, fullTrustAssembly);
return (Sandbox)Activator.CreateInstanceFrom(domain, typeof(Sandbox).Assembly.ManifestModule.FullyQualifiedName, typeof(Sandbox).FullName).Unwrap();
}
public bool CreateInstance(string assemblyPath, string scriptType)
{
new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, assemblyPath).Assert();
var assembly = Assembly.LoadFrom(assemblyPath);
CodeAccessPermission.RevertAssert();
Type type = assembly.GetType(scriptType);
if (type == null)
return false;
instance = Activator.CreateInstance(type);
return instance != null;
}
public object Execute(string method, params object[] parameters)
{
Type type = instance.GetType();
MethodInfo info = type.GetMethod(method);
return info.Invoke(instance, parameters);
}
}
private static void CompileToFile(string code, string ifaceFile, string output)
{
CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
CompilerParameters p = new CompilerParameters();
p.GenerateInMemory = false;
p.GenerateExecutable = false;
p.OutputAssembly = output;
provider.CompileAssemblyFromSource(p, code, ifaceFile);
}
private static string code = @"
using Plugin;
class MyPlugin : IPlugin
{
public void DoStuff(Data data)
{
}
}
";
static void Main(string[] args)
{
string iface = System.IO.File.ReadAllText(@"C:\Documents and Settings\markus.BLUE\mina dokument\visual studio 2010\Projects\Plugin\Plugin\IPlugin.cs");
string pluginObjectFile = System.IO.Path.GetTempFileName();
CompileToFile(code, iface, pluginObjectFile);
Sandbox s = Sandbox.Create();
s.CreateInstance(pluginObjectFile, "MyPlugin");
Data data = new Data();
s.Execute("DoStuff", data);
}
}
}
答案 0 :(得分:0)
它必须是您沟通双方都知道的类型!