我正在尝试从由用CompilerResults.CompiledAssembly
动态生成的程序集加载的对象执行方法。但是,我需要该程序集具有受限的权限,因为它包含的方法具有意外的行为。
我进行了很多搜索,Microsoft文档建议使用.NET Framework 4提供的安全功能。This是我所阅读的有关沙箱的众多资源之一,它使用了不同的{{ 1}}具有受限的权限。从理论上讲,我可以从受限制的AppDomain
中加载的程序集中的类创建实例,并且该实例将被视为远程对象。
要使用新对象作为参考,如果该类扩展了AppDomain
类,则在尝试访问该对象时会在内部创建一个代理。就我而言,扩展MarshalByRefObject
的类位于层次结构的顶部。
基于我之前提到的链接的简化代码是:
MarshalByRefObject
上面的代码有效,程序集被加载到var permissionSet = ...;
var dllPath = ...;
// Create the AppDomainSetup
var info = new AppDomainSetup
{
// Set the path to the assembly to load.
ApplicationBase = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
};
var strongName = assembly.Evidence.GetHostEvidence<StrongName>();
// Create the domain
var sandboxDomain = AppDomain.CreateDomain("RestrictedDomain", null, info, permissionSet, new StrongName[] { strongName });
var handle = Activator.CreateInstanceFrom(sandboxDomain, dllPath, "MyNamespace.MyClass");
var myLoadedTypeInstance = handle.Unwrap() as MyClass;
中(只能引用它的dll位置而不是它的名称来实现)。但是,当我尝试使用AppDomain
中带有两个可序列化参数的方法时,出现异常。呼叫类似于myLoadedTypeInstance
,但例外是:
“此代理不支持方法InitializeLifetimeService,如果该方法未标记有OperationContractAttribute或接口类型未标记有ServiceContractAttribute,则可能会发生这种情况。”
一些细节:
myLoadedTypeInstance.MyMethod(param1, param2)
创建的TChannel
类型的属性。ChannelFactory<T>.CreateChannel()
,我可以访问所有远程对象的生命周期信息。RemotingServices.GetLifetimeService(myLoadedTypeInstance) as ILease
提供的URL使用Activator.GetObject()
显式地将其视为远程对象,这是多余的,因为我最终创建了该对象的两个实例。但这是一个绝望的举止,有着相同的结局。