我有一个代码片段,使用脚本引擎编译脚本并将程序集作为字节数组检索。
现在我想在沙盒中加载这个Assembly
,这是我的代码:
Assembly _dynamicAssembly;
ScriptEngine _engine;
Session _session;
public string Execute(string code)
{
// Setup sandbox
var e = new Evidence();
e.AddHostEvidence(new Zone(SecurityZone.Internet));
var ps = SecurityManager.GetStandardSandbox(e);
var setup = new AppDomainSetup
{ ApplicationBase = Environment.CurrentDirectory };
var domain =
AppDomain.CreateDomain("Sandbox",
AppDomain.CurrentDomain.Evidence, setup, ps);
AppDomain.CurrentDomain.AssemblyResolve += DomainAssemblyResolve;
// Process code
var submission = _engine.CompileSubmission<object>(code, _session);
submission.Compilation.Emit(memoryStream);
var assembly = memoryStream.ToArray();
_dynamicAssembly = Assembly.Load(assembly);
var loaded = domain.Load(assembly);
// Rest of the code...
}
这是AssemblyResolve事件处理程序:
Assembly DomainAssemblyResolve(object sender, ResolveEventArgs args)
{
return _dynamicAssembly;
}
这意味着当我执行 domain.Load(assembly)
时,如果我没有订阅该事件并返回该 Assembly
,我将得到 _dynamicAssembly, 如果不这样做,则会出现 FileNotFoundException
。
以上代码可以编译和运行,但问题在于在域程序集中执行的代码实际上并未在沙箱中执行。 当获取提交方法并调用其中的工厂后,返回此 AppDomain.CurrentDomain.FriendlyName
,结果是:MyRoslynApplication.vshost.exe
,而不是沙箱的 AppDomain
。我是否以错误的方式加载了我的
byte[]
程序集?
CreateInstanceFromAndUnwrap
需要一个物理文件,对吗?编辑针对您的编辑,我无法从磁盘加载,因为那将需要IO权限。 - Filip Ekbergbyte[]
加载的笨拙之外,你仍然需要做一些设计工作,以找出如何代理一个适应你的“脚本”供你的应用程序使用的接口。至少,你需要一个MarshalByRefObject和某种形式的接口来为你的服务提供独立于动态加载程序集的支持。 - Dan Bryant