程序集无法加载到受限的 AppDomain
Posted
技术标签:
【中文标题】程序集无法加载到受限的 AppDomain【英文标题】:Assembly fails to load in restricted AppDomain 【发布时间】:2016-05-25 06:26:28 【问题描述】:我正在尝试将程序集加载到受限制的 AppDomain 中。如果我不指定任何限制,程序集将正确加载:
var permissionSet = new PermissionSet(System.Security.Permissions.PermissionState.Unrestricted);
AppDomain targetAppDomain = AppDomain.CreateDomain("LockedDomain" + Guid.NewGuid().ToString("N"),null,domainSetup,permissionSet,null);
var instance = (IRemoteFilterClass) targetAppDomain.CreateInstanceFromAndUnwrap(tempAssemblyPath, "CompiledCode.CompiledClass");
但是我想尽可能完全地锁定创建的 AppDomain,即只授予绝对必要的权限。如果我指定一个 PermissionSet 来限制权限,则程序集无法加载:
var permissionSet = new PermissionSet(System.Security.Permissions.PermissionState.None);
permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, tempAssemblyPath));
permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.PathDiscovery, tempAssemblyPath));
permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, Assembly.GetExecutingAssembly().Location));
permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.PathDiscovery, Assembly.GetExecutingAssembly().Location));
permissionSet.AddPermission(new ReflectionPermission(PermissionState.Unrestricted)); //Not sure if this is necessary, but does not work anyway
AppDomain targetAppDomain = AppDomain.CreateDomain("LockedDomain" + Guid.NewGuid().ToString("N"),null,domainSetup,permissionSet,null);
var instance = (IRemoteFilterClass) targetAppDomain.CreateInstanceFromAndUnwrap(tempAssemblyPath, "CompiledCode.CompiledClass");
抛出以下异常:
System.IO.FileLoadException: Could not load file or assembly '5e1a72b7c5584f7c92c18ea9b221222f, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. Failed to grant permission to execute. (Exception from HRESULT: 0x80131418) ---> System.Security.Policy.PolicyException: Execution permission cannot be acquired.
at System.Security.CodeAccessSecurityEngine.ResolveGrantSet(Evidence evidence, Int32& specialFlags, Boolean checkExecutionPermission)
--- End of inner exception stack trace ---
at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, Boolean suppressSecurityChecks, StackCrawlMark& stackMark)
at System.Reflection.Assembly.LoadFrom(String assemblyFile, Evidence securityEvidence)
at System.Activator.CreateInstanceFromInternal(String assemblyFile, String typeName, Boolean ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, Evidence securityInfo)
at System.AppDomain.CreateInstanceFrom(String assemblyFile, String typeName)
at System.AppDomain.CreateInstanceFromAndUnwrap(String assemblyName, String typeName)
at System.AppDomain.CreateInstanceFromAndUnwrap(String assemblyName, String typeName)
似乎仍然缺少权限,但我不知道缺少哪些权限。
【问题讨论】:
【参考方案1】:需要在SecurityPermissionFlag.Execution
集合中添加SecurityPermission
。
这是工作代码:
var permissionSet = new PermissionSet(System.Security.Permissions.PermissionState.None);
permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, tempAssemblyPath));
permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.PathDiscovery, tempAssemblyPath));
//The following line fixed the code
permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
AppDomain targetAppDomain = AppDomain.CreateDomain("LockedDomain" + Guid.NewGuid().ToString("N"),null,domainSetup,permissionSet,null);
var instance = (IRemoteFilterClass) targetAppDomain.CreateInstanceFromAndUnwrap(tempAssemblyPath, "CompiledCode.CompiledClass");
(来源:https://social.msdn.microsoft.com/Forums/vstudio/en-US/23a9197e-3581-4a28-912d-968004488773/how-to-change-permissions-of-appdomain?forum=clr)
【讨论】:
以上是关于程序集无法加载到受限的 AppDomain的主要内容,如果未能解决你的问题,请参考以下文章
无法在新的 AppDomain 中创建 UserControl
尝试通过反射加载应用程序并获取错误“无法加载文件或程序集......系统找不到指定的文件。”
从另一个 WPF 应用程序加载 WPF 应用程序程序集,出现错误:无法在同一个 AppDomain 中创建多个 System.Windows.Application 实例