AppDomain证据没有区域?

时间:2012-06-24 09:34:24

标签: c# .net

什么是控制当前应用域的证据?

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窗体桌面应用程序的默认应用程序域中这些值的内容?

2 个答案:

答案 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)

事实证明,罪魁祸首确实是一个“不寻常的部署方案”,就像汉斯在我的问题评论中所建议的那样。我们对一些组件使用加密(包络),显然这会篡改隔离存储所需的证据。