Figures
Figure 2
Figure 2
Figure 2 Commonly used Shim APIs
API
Description
CorBindToRuntimeEx
The main entry point to the shim. Use to load a particular version of the runtime into the process.
GetCorVersion
Returns the version of the runtime loaded into the current process.
GetCorSystemDirectory
Returns the install directory for the version of the runtime that is loaded in the current process.
Figure 3 Calling CorBindToRuntimeEx
LPWSTR pszVer = L"v1.0.2121";
LPWSTR pszFlavor = L"wks";
ICorRuntimeHost *pHost = NULL;
hr = CorBindToRuntimeEx(
                      //version
                      pszVer,       
                      // svr or wks                        
                      pszFlavor,    
                      //domain-neutral"ness" and gc settings
                      STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST |        
                      STARTUP_CONCURRENT_GC, 
                      CLSID_CorRuntimeHost, 
                      IID_ICorRuntimeHost, 
                      (void **)&pHost);
if (SUCCEEDED(hr))
{
}
Figure 4 Loader Optimization Settings
Setting
Description
No assemblies are loaded domain-neutral (except mscorlib, which is always loaded domain-neutral)
This setting is termed "Single Domain" because it is commonly used when the host is running a single application in the process. Pass STARTUP_LOADER_ OPTIMIZATION_SINGLE_DOMAIN as the dwFlags parameter to CorBindToRuntimeEx.
All assemblies are loaded domain-neutral
This setting is typically used when there are multiple domains in the process, all running the same code. For example, a host may choose to run the same application in numerous domains isolated by user. Pass STARTUP_LOADER_ OPTIMIZATION_MULTI_DOMAIN as the dwFlags parameter to CorBindToRuntimeEx.
Shared assemblies (those with strong names) are loaded domain-neutral
Use this setting when running multiple different applications in the same process. Pass STARTUP_LOADER_ OPTIMIZATION_MULTI_DOMAIN_HOST as the dwFlags parameter to CorBindToRuntimeEx. Strong names is the naming technique used to ensure that shared assemblies (those that are used by more than one application) have globally unique names and that the assembly hasn't been altered, either accidentally or maliciously, from the time it was built to the time it was deployed.
Figure 5 ICorConfiguration Methods
Method
Description
SetAppDomainLoadEvent
Registers a callback that notifies the host when a new application domain has been created in the process.
SetGCThreadControl
Registers a callback that allows the host to schedule threads for non-runtime tasks when they would otherwise be blocked for a GC.
SetGCHostControl
Allows the host to customize the size of the GC heap used by the CLR.
SetDebuggerThreadControl
Registers a callback that allows the host to be notified when threads are started and stopped by the debugger.
AddDebuggerSpecialThread
Allows the host to indicate to the debugging services that a particular thread should be allowed to continue executing while the debugger has an application stopped.
Figure 7 Loading Hosting Code
// import the type library that defines the COM interfaces used to access 
// the managed class in the mscorlib.  Specifically, we need to call      
// through _AppDomain to an instance of the managed class               
// System.AppDomain.  This typelib ships in the SDK
#import <mscorlib.tlb> raw_interfaces_only 
high_property_prefixes("_get","_put","_putref")
using namespace ComRuntimeLibrary;

// import the type library for our managed hosting code.  This typelib  
// was built using the tlbexp SDK tool
#import <MyManagedHost.tlb> raw_interfaces_only 
high_property_prefixes("_get","_put","_putref")
using namespace MyManagedHost;

// Declare a variable to hold the hosting interface
ICorRuntimeHost *pCLR = NULL;

// Load the CLR by calling CorBindToRuntime and get back an IP to 
// ICorRuntimeHost as shown in the 
// previous code sample (code is omitted here)

// Get the default domain
_AppDomain *pDefaultDomain = NULL;
IUnknown   *pAppDomainPunk = NULL;

HRESULT hr = pCLR->GetDefaultDomain(&pAppDomainPunk);
_ASSERT(pAppDomainPunk); 

 hr = pAppDomainPunk->QueryInterface(__uuidof(_AppDomain), 
                                        (void**) &pDefaultDomain);
_ASSERT(pDefaultDomain);

// Create an instance of HostProcessRequest in MyManagedHost.dll.  The  
// interface pointer to the instance of HostProcessRequest is used from 
// now on to direct user requests into managed code.

_ObjectHandle *pObjHandle = NULL;
hr = pDefaultDomain->CreateInstance(
    _bstr_t("MyManagedHost")),       // assembly name
    _bstr_t("HostProcessRequest")),  // type name
    &pObjHandle);                    // returned handle to object

_ASSERT(pObjHandle);

VARIANT v;
VariantInit(&v);
hr = pObjHandle->Unwrap(&v);

_ASSERT(v.pdispVal);
_HostProcessRequest *pPR = NULL;
hr = v.pdispVal->QueryInterface(__uuidof(_HostProcessRequest), 
                                (void**) &pPR);
_ASSERT(pPR);

// Remember to call Release() on everything!
Figure 8 Registering to Receive the TypeResolveEvent
Public class Host
{
   private Assembly TLoadHandler(System.Object sender, EventArgs e)
   {
        // find the assembly or create one and return it.    
   }
    public static void Main(string[] args)
    {
       Host host = new Host();
       AppDomain appDomain = AppDomain.CreateDomain("MyDomain",
                                                    null,
                                                    null,
                                                    null);
    // hook up the handler
    ResolveEventHandlertrh= new ResolveEventHandler ( host.TLoadHandler);
    appDomain.AddOnTypeResolve(trh);

    // run the app, etc ...
}
Figure 9 Creating the Domain-level Policy
Using System.Security:
Using System.Security.Policy;
Using System.Security.Permissions;
// Create the domain-level policy
PolicyLevel    pl   = PolicyLevel.CreateAppDomainLevel();

// include a code group that gives permissions only to assemblies
// that are strong named with s_somePublicKey
UnionCodeGroup snCG = new UnionCodeGroup( 
              new StrongNameMembershipCondition(new
              StrongNamePublicKeyBlob( s_somePublicKey ), null, null ), 
  new PolicyStatement(new PermissionSet(PermissionState.Unrestricted)));

pl.RootCodeGroup.AddChild(snCG);

AppDomain appDomain = AppDomain.CreateDomain("MyDomain",
                                             null,
                                             null,
                                             null);

// set our new policy as the domain-level policy
appDomain.SetAppDomainPolicy(pl);
Page view tracker