什么在控制当前应用程序域的证据?
var evidence = Thread.GetDomain().Evidence;
什么控制它是空还是非空,什么决定它的内容?
当我的应用程序从域证据查询这些主机证据对象时
var z = evidence.GetHostEvidence<Zone>
var p = evidence.GetHostEvidence<Publisher>
var s = evidence.GetHostEvidence<Site>
var n = evidence.GetHostEvidence<StrongName>
var u = evidence.GetHostEvidence<Url>
在某些环境中执行时,它们有时似乎全部为空。我之所以相信这是在 IsolatedStorage._GetAccountingInfo(...)
内部抛出的异常,通过查看反射器中的代码可以清楚地看出,只有在域证据包含 null 时才会抛出此异常对于所有上述主机证据对象。这将导致隔离存储无法初始化。
不幸的是,我无法在我自己的系统上重现它。例如,区域值始终是一个正确的值,表示“我的电脑”,所以我正在努力解决这个问题。
什么控制 Windows 窗体桌面应用程序的默认应用程序域中这些值的内容?
最佳答案
当您的代码是 COM object accessed by a native Win32 application 时,会发生类似的情况(默认 AppDomain
的 Evidence
为空),或者加载时 run inside of the command line version of PowerShell.exe 。我在使用 OpenXML(特别是 EPPlus )程序集时遇到了这个问题,当 Office 文档超过一定的文件大小时,该程序集使用isolatedStorage。
我更喜欢使用反射来处理当前的 AppDomain
,而不是在默认的 AppDomain 内部旋转另一个 AppDomain
并处理额外级别的编码/远程处理。的证据。
这是 C# 中的概念证明:
using System;
namespace AppDomainEvidence
{
class Program
{
static void Main(string[] args)
{
var initialAppDomainEvidence = System.Threading.Thread.GetDomain().Evidence; // Setting a breakpoint here will let you inspect the current AppDomain's evidence
try
{
var usfdAttempt1 = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForDomain(); // This will fail when the current AppDomain Evidence is instantiated via COM or in PowerShell
}
catch (Exception e)
{
// Set breakpoint here to inspect Exception "e"
}
// Create a new Evidence that include the MyComputer zone
var replacementEvidence = new System.Security.Policy.Evidence();
replacementEvidence.AddHostEvidence(new System.Security.Policy.Zone(System.Security.SecurityZone.MyComputer));
// Replace the current AppDomain's evidence using reflection
var currentAppDomain = System.Threading.Thread.GetDomain();
var securityIdentityField = currentAppDomain.GetType().GetField("_SecurityIdentity", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
securityIdentityField.SetValue(currentAppDomain,replacementEvidence);
var latestAppDomainEvidence = System.Threading.Thread.GetDomain().Evidence; // Setting a breakpoint here will let you inspect the current AppDomain's evidence
var usfdAttempt2 = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForDomain(); // This should work
}
}
}
这是我在 PowerShell 中实现的解决方法:
# This one will fail
$usfd = [System.IO.IsolatedStorage.IsolatedStorageFile]::GetUserStoreForDomain()
# Inspect the current AppDomain's Evidence
[threading.thread]::GetDomain().Evidence
# Modify the current AppDomain's Evidence
$evidence = new-object System.Security.Policy.Evidence
$zone = new-object System.Security.Policy.Zone('MyComputer')
$evidence.AddHost($zone)
$currentAppDomain = [threading.thread]::GetDomain()
$securityIdentityField=$currentAppDomain.GetType().GetField('_SecurityIdentity','Instance,NonPublic')
$securityIdentityField.SetValue($currentAppDomain, $evidence)
# Inspect the current AppDomain's Evidence
[threading.thread]::GetDomain().Evidence
# This one will succeed
$usfd = [System.IO.IsolatedStorage.IsolatedStorageFile]::GetUserStoreForDomain()
关于c# - AppDomain 证据没有区域?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11176363/