2012-06-24 15 views
2

什麼是控制當前應用程序域的證據?AppDomain Evidence沒有區域?

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時,纔會拋出此異常。這會導致獨立存儲無法初始化。

不幸的是,我不能在我自己的系統上重現它。例如,Zone值總是一個合適的值,表示「我的電腦」,所以我正在努力解決這個問題。

什麼控制這些值在Windows窗體桌面應用程序的默認應用程序域中的內容?

+0

它是由CLR主機時,它會創建主域初始化。隨着EvidenceBase的推出,.NET 4的重大變化,所以我會尋找仍然使用遺留證據的不尋常的託管方案。包括ClickOnce和進程內並行COM激活。 –

+0

謝謝漢斯。它是通過普通MSI部署的.NET 4 winforms應用程序。所以在使用.NET4的普通機器上正常執行時會出現問題。域名證據與大會證據有什麼區別?在我的集會上,我預計大部分證據都會被遺漏,因爲它沒有很強的名字。 –

回答

0

事實證明,罪魁禍首確實是一個「不尋常的部署方案」,正如漢斯在對我的問題發表評論時所建議的那樣。我們對一些組件使用加密(包絡),顯然這會篡改孤立存儲所需的證據。

2

當您的代碼爲COM object accessed by a native Win32 application(默認AppDomainEvidence爲空)或加載時出現類似情況,並且run inside of the command line version of PowerShell.exe。當Office文檔超過特定文件大小時,我使用OpenXML(特別是EPPlus)程序集使用IsolatedStorage時遇到了此問題。

與其在默認的內部旋轉另一個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() 
+1

謝謝,你的帖子非常有幫助。我遇到了同樣的問題(SpreadsheetLight,它也使用OpenXML)。我首先嚐試了「旋轉另一個AppDomain」的方法,當試圖通過序列化在AppDomain遠程邊界上傳遞大型DataTable時,這種方法很快就會耗盡內存。您的解決方案完美運作 – Heinzi

+1

謝謝你太棒了!我有一個類似的問題,試圖調試使用OpenXML的Office Addin。我不斷收到錯誤IsolatedStorageFile無法確定域的身份。此代碼修復了我的AppDomain,並允許我的代碼無誤地運行! – snoopen

相關問題