为啥新的 AppDomain 会加载不必要的 DLL?
Posted
技术标签:
【中文标题】为啥新的 AppDomain 会加载不必要的 DLL?【英文标题】:Why does a new AppDomain load unnecessary DLLs?为什么新的 AppDomain 会加载不必要的 DLL? 【发布时间】:2015-04-17 17:42:23 【问题描述】:我有一个 asp.net web api,它具有执行一些动态生成的 DLL 的逻辑。 我想创建一个具有受限权限集的新沙盒 AppDomain 来执行这些 DLL。
这是创建新的受限应用域的方法:
public static AppDomain CreateRestrictedDomain(string applicationBasePath)
PermissionSet permissionSet = new PermissionSet(PermissionState.None);
permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, applicationBasePath));
AppDomainSetup appDomainSetup = new AppDomainSetup
ApplicationBase = applicationBasePath,
DisallowCodeDownload = true,
DisallowBindingRedirects = true,
DisallowPublisherPolicy = true,
LoaderOptimization = LoaderOptimization.MultiDomainHost,
;
AppDomain restrictedDomain = AppDomain.CreateDomain(
friendlyName: "MySandbox",
securityInfo: null,
info: appDomainSetup,
grantSet: permissionSet,
fullTrustAssemblies: null);
return restrictedDomain;
我第一次引用新的appDomain时遇到的问题,例如只是为了读取 appDomain.FriendlyName,框架会尝试将当前应用程序中存在的一些依赖项加载到新的 AppDomain。如果依赖项不在 GAC 中,它会尝试在 applicationBasePath 中找到它们,并且会失败,因为 applicationBasePath 设置为仅存储不受信任的 DLL 的文件夹。
我的问题是为什么创建一个新的 AppDomain 会触发这些额外依赖项的加载。在我上面的 CreateRestrictedDomain 方法中,没有引用任何这些依赖项。
我在 VS 2013 中使用默认模板创建了一个新的 asp.net 项目,并在索引控制器中使用上面的代码创建了一个新的 AppDomain,并打印出名称。代码如下:
public ActionResult Index()
var tempPath = Path.GetTempPath();
var untrustedPath = Path.Combine(tempPath, "unstrusted");
if (!Directory.Exists(untrustedPath))
Directory.CreateDirectory(untrustedPath);
var appDomain = AppDomainSandboxHelper.CreateRestrictedDomain(untrustedPath);
var friendlyName = appDomain.FriendlyName;
ViewBag.Title = friendlyName;
return View();
当我在调试模式下运行时,我可以看到读取 appDomain.FriendLyName 的行会触发 System.Web.dll 被加载到新的 AppDomain "MySandbox"
'iisexpress.exe' (CLR v4.0.30319: Domain 4): Loaded 'C:\windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll'. Symbols loaded.
'iisexpress.exe' (CLR v4.0.30319: MySandbox): Loaded 'C:\windows\Microsoft.Net\assembly\GAC_64\System.Web\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Web.dll'. Symbols loaded.
为什么 System.Web.dll 需要加载到新的 AppDomain 中?
【问题讨论】:
【参考方案1】:为securityInfo
传递null
使用当前正在执行的AppDomain 的证据。
AppDomain.CreateDomain:
安全信息
类型:System.Security.Policy.Evidence
确定在应用程序域中运行的代码的身份的证据。传递 null 以使用当前的证据 应用领域。
很可能需要加载 System.Web.dll
程序集以检查其证据。
【讨论】:
我通过了证据:Evidence evidence = new Evidence();证据.AddHostEvidence(新区域(SecurityZone.Untrusted));到方法。但这没有任何区别。我仍然可以看到 System.Web.dll 加载到新的 AppDomain 中。【参考方案2】:原来是因为我在现有的 ASP.NET 拥有的 AppDomain 中创建了一个 AppDomain。 ASP.NET 将其自己的 AppDomainManager 安装到父 AppDomain 中,并且这会自动向下传播到子 AppDomain,除非调用者显式覆盖,如下所示
AppDomainSetup appDomainSetup = new AppDomainSetup
ApplicationBase = applicationBasePath,
DisallowCodeDownload = true,
DisallowBindingRedirects = true,
DisallowPublisherPolicy = true,
LoaderOptimization = LoaderOptimization.MultiDomainHost,
AppDomainManagerAssembly = "", // overridden by caller
AppDomainManagerType = "" // overridden by caller
;
【讨论】:
以上是关于为啥新的 AppDomain 会加载不必要的 DLL?的主要内容,如果未能解决你的问题,请参考以下文章
如何在新的 AppDomain 中运行从加载到引用的程序集的方法
无法在新的 AppDomain 中创建 UserControl