通過托管代碼來管理CLR的方式,稱為托管宿主。想實現托管宿主很簡單,只要實現System.AppDomainManager類就可以了。AppDomainManager類的定義如代碼清單1-1所示。
代碼清單1-1 AppDomainManager類定義
[ComVisibleAttribute(true)]
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
[SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.Infrastructure)]
public classAppDomainManager : MarshalByRefObject
要實現自己的托管宿主需要實現一個AppDomainManager類的子類,重寫其中的虛方法。代碼清單1-2自定義XHAppDomainManager類來實現簡單的托管宿主。
代碼清單1-2自定義XHAppDomainManager類
namespace 托管宿主
{
[GuidAttribute("F4D15099-3407-4A7E-A607-DEA440CF3891")]
[SecurityPermissionAttribute(SecurityAction.LinkDemand,
Flags = SecurityPermissionFlag.Infrastructure)]
[SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.Infrastructure)]
class XHAppDomainManager:AppDomainManager
{
private HostSecurityManagerXHHostSecurityManager = null;
public override void InitializeNewDomain(AppDomainSetupappDomainInfo)
{
Console.WriteLine(" XH AppDomain Manager ");
XHHostSecurityManager = AppDomain.CurrentDomain.CreateInstanceAndUnwrap(
"XHSecurityManager, Version=1.0.0.3, Culture=neutral, "+
"PublicKeyToken=5659fc598c2a503e",
"托管宿主.XHHostSecurityManager") as HostSecurityManager;
Console.WriteLine(" Custom Security Manager Created.");
}
public override HostSecurityManager HostSecurityManager
{
get
{
return XHHostSecurityManager;
}
}
public override AssemblyEntryAssembly
{
get
{
return base.EntryAssembly;
}
}
}
}
現在通過代碼清單3-14創建的宿主應用程序能夠參與新應用程序域的創建。在代碼中聲明了兩個權限,重寫了兩個屬性,在實際的編碼中可以按照這樣的簡單模式進行擴展,真正的參與CLR的管理。
編寫托管宿主之後,如何讓它發揮作用呢?一般情況有三種選擇:
非托管API
關於非托管API在CLR寄宿一節進行了詳細的介紹,但是在討論CLR寄宿的時候只討論了完全采用非托管API實現的非托管宿主實施的寄宿。那麼想要通過非托管API來使托管宿主發揮作用的話,必須在非托管API啟動CLR之後把控制權轉交給我們的托管宿主。宿主在調用 CorBindToRuntimeEx之後,將請求指向 ICorRuntimeHost 的接口指針,利用該指針轉向到托管宿主。
環境變量
在 APPDOMAIN_MANAGER_ASM 和 APPDOMAIN_MANAGER_TYPE 環境變量中標識替代的AppDomainManager的程序集和類型。該程序集必須完全受信任,並且包含在起始應用程序的全局程序集緩存或目錄中。環境變量中的類型和程序集名稱必須是完全限定的。例如:
set APPDOMAIN_MANAGER_TYPE=MyNamespace.TestAppDomainManager
set APPDOMAIN_MANAGER_ASM=customappDomainmanager, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f1368f7b12a08d72
注意只有被授予 FullTrust 的程序集(如全局程序集緩存中的程序集或者在 AppDomain.CreateDomain(String, Evidence, AppDomainSetup, PermissionSet, array<StrongName>[]()[]) 方法中標識為fullTrustAssemblies的程序集)才可以在 AppDomainManager 構造函數和 InitializeNewDomain方法中加載。
注冊表值
在啟動CLR之前,HKEY_LOCAL_MACHINE(or HKEY_CURRENT_USER)\Software\Microsoft\.NETFramework\鍵值必須設置兩個值,一個是APPDOMAIN_MANAGER_ASM,另一個是APPDOMAIN_MANAGER_TYPE。APPDOMAIN_MANAGER_ASM必須是安裝到全局程序集緩存的程序集,APPDOMAIN_MANAGER_TYPE是自定義的托管宿主的類。
注:本文部分內容改編自《.NET 安全揭秘》
作者:玄魂
出處:http://www.cnblogs.com/xuanhun/
查看本欄目