2011-01-28 44 views
11

我通過Microsoft .NET Framework的工作 - 應用程序開發基礎培訓工具包書第8章第2課:配置應用程序域尋求替代AppDomain.CreateDomain(字符串,證據)由於過時的CAS策略

ShowWinIni是因爲我想執行

object[] hostEvidence = { new Zone(SecurityZone.MyComputer) }; 
Evidence e = new Evidence(hostEvidence, null); 

// Create an AppDomain. 
AppDomain d = AppDomain.CreateDomain("New Domain", e); 

// Run the assembly 
d.ExecuteAssemblyByName("ShowWinIni"); 

程序集名稱當我執行:

AppDomain d = AppDomain.CreateDomain("New Domain", e); 

我得到以下信息: 「此方法隱式使用已被.NET Framework廢棄的CAS策略。爲了兼容性原因啓用CAS策略,請使用NetFx40_LegacySecurityPolicy配置開關。請參閱http://go.microsoft.com/fwlink/?LinkID=155570以獲取更多信息。」

時,我沒有證據對象創建一個AppDomain我可以執行大會罰款。

當然,筆者走訪了http://go.microsoft.com/fwlink/?LinkID=155570但我仍然困惑,如何創建一個應用程序域與指定的權限。

下一個最有幫助的網站,我發現http://msdn.microsoft.com/en-us/library/bb763046.aspx但我強名稱對象計算爲NULL。

StrongName fullTrustAssembly = 
    typeof(Program).Assembly.Evidence.GetHostEvidence<StrongName>(); 

計劃之中實現所有這些代碼的類的名稱。

在此先感謝您的建議和提示!

回答

11

我發現了一種方法來使原始代碼示例工作,而無需啓用NetFX40_LegacySecurityPolicy。

EvidenceBase[] hostEvidence = { new Zone(SecurityZone.MyComputer) }; 
Evidence e = new Evidence(hostEvidence, null); 

AppDomain d = AppDomain.CreateDomain("New Domain", e); 

d.ExecuteAssemblyByName("ShowWinIni"); 

如果你改變了SecurityZone到上網本將無法正常工作,它會嘗試使用導致NotSupportedException異常的已經過時的CAS安全策略。我想要的是一個SecurityException ...意味着我想執行的程序集沒有它需要的權限。

要在具有有限權限的AppDomain中執行程序集,您需要使用沙盒。我發現沙箱的最佳例子是這裏: http://www.simple-talk.com/dotnet/.net-framework/whats-new-in-code-access-security-in-.net-framework-4.0---part-i/

我認爲該頁面還解釋了在4.0中對CAS進行的更改非常好!

許多來源,包括MSDN,讓我相信我需要提供一個強名稱數組調用時:

AppDomain.CreateDomain(string friendlyName, 
         Evidence securityInfo, 
         AppDomainSetup info, 
         PermissionSet grantSet, 
         params StrongName[] fullTrustAssemblies); 

正如我在原來的職位說,我是(現在仍然是)遇到了麻煩一個強名稱對象而不是null。原來我甚至都不需要它!

這是我沙盒完成例如:

Evidence ev = new Evidence(); 
ev.AddHostEvidence(new Zone(SecurityZone.Internet)); 
PermissionSet internetPS = SecurityManager.GetStandardSandbox(ev); 

AppDomainSetup adSetup = new AppDomainSetup(); 
adSetup.ApplicationBase = Path.GetFullPath(pathToUntrusted); 

AppDomain newDomain = AppDomain.CreateDomain("Sandbox Domain", null, adSetup, internetPS); 

newDomain.ExecuteAssemblyByName(untrustedAssembly); 

pathToUntrusted =文件路徑的字符串表示我的組件

untrustedAssembly =集名稱的字符串表示

7

在向同事尋求幫助後,我得到了這個工作。

顯然,本書的練習是在.Net的3.5框架中使用的,而我使用的是4.0。修改我的項目和ShowWinIni項目屬性以使用3.5框架後,一切正常......但我仍然希望使用4.0框架進行這項工作。

解決以下消息:。 「這種方法隱式使用CAS策略,已廢棄由.NET Framework爲了使兼容性的原因CAS策略,請使用NetFx40_LegacySecurityPolicy配置開關請參閱http://go.microsoft.com/fwlink/?LinkID=155570爲更多信息。」

我創建了一個app.config文件,並添加以下代碼行:

<configuration> 
    <runtime> 
     <NetFx40_LegacySecurityPolicy enabled="true"/> 
    </runtime> 
</configuration> 

您可以在http://msdn.microsoft.com/en-us/library/dd409253.aspx

這最終使我的程序不受信任的應用程序閱讀更多關於NetFx40_LegacySecurityPolicy,拋出一個安全當我嘗試調試時出現異常。爲了讓我的應用程序再次可靠,我啓用了ClickOnce安全設置並在我的項目屬性中標記了「這是完全信任的應用程序」。

在這一點上,我可以調試我的程序,但現在一個安全異常被拋出,當我執行該語句:

d.ExecuteAssemblyByName("ShowWinIni"); 

此語句工作正常之前,我開始嘗試包括證據的對象,我創建的時候我的AppDomain對象。那麼事實證明還有另一種方法... AppDomain。ExecuteAssemblyByName(字符串,證據),你可以在http://msdn.microsoft.com/en-us/library/5kd4z003.aspx閱讀。所以我用以下代碼替換了上面的代碼片段:

d.ExecuteAssemblyByName("ShowWinIni", e); 

'e'是我在我的原始問題中創建的證據對象。

現在我不認爲這是最好的解決方案。理想情況下,我寧願不強迫我的程序使用NetFx40_LegacySecurityPolicy,我相信真實世界的應用程序不應該依賴過時的方法。我認爲這個解決方案值得發佈,任何人都應該通過與我一樣的書。