什么是控制当前应用域的证据?
var evidence = Thread.GetDomain().Evidence;
什么控制它是null还是非null,是什么决定它的内容?
当我的应用程序从域证据
中查询这些主机证据对象时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窗体桌面应用程序的默认应用程序域中这些值的内容?
答案 0 :(得分:2)
当您的代码为COM object accessed by a native Win32 application(默认AppDomain
的{{1}}为空)或加载run inside of the command line version of PowerShell.exe时,会出现类似情况。当Office文档超过特定文件大小时,使用OpenSML(特别是EPPlus)程序集时,我遇到了这个问题。
我宁愿使用反射来清除当前Evidence
的证据,而不是在默认的另一级AppDomain
内进行操作,而是处理额外级别的Marshaling / Remoting。
以下是C#中的概念证明:
AppDomain
这是我在PowerShell中实现的解决方法:
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
}
}
}
答案 1 :(得分:0)
事实证明,罪魁祸首确实是一个“不寻常的部署方案”,就像汉斯在我的问题评论中所建议的那样。我们对一些组件使用加密(包络),显然这会篡改隔离存储所需的证据。