c# - AppDomain 证据没有区域?

标签 c# .net

什么在控制当前应用程序域的证据?

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 时,会发生类似的情况(默认 AppDomainEvidence 为空),或者加载时 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/

相关文章:

c# - 带有参数发送者和 RoutedEventArgs 的 WPF 调用方法

c# - 如何从html链接中提取电子邮件

javascript - 如何使一个部分占据 Dynamics CRM 表单编辑器中的整个空间

c# - 无法加载文件或程序集 System.Runtime

c# - form.dispose() 总是调用验证事件并显示弹出消息

c# - 发票和账单在一个表中?

c# - 如何从 Bson 文档中获取值列表?

c# - 网络 API : Same Method with different HTTP Verbs

c# - 将实例化属性绑定(bind)到 UI

C# 字符串 - 创建未转义的反斜杠