Figure 2
Figure 2
Figure 2 Commonly used Shim APIs
The main entry point to the shim. Use to load a particular version of the runtime into the process.
Returns the version of the runtime loaded into the current process.
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(
                      // svr or wks                        
                      //domain-neutral"ness" and gc settings
                      (void **)&pHost);
if (SUCCEEDED(hr))
Figure 4 Loader Optimization Settings
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
Registers a callback that notifies the host when a new application domain has been created in the process.
Registers a callback that allows the host to schedule threads for non-runtime tasks when they would otherwise be blocked for a GC.
Allows the host to customize the size of the GC heap used by the CLR.
Registers a callback that allows the host to be notified when threads are started and stopped by the debugger.
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 
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 
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);

 hr = pAppDomainPunk->QueryInterface(__uuidof(_AppDomain), 
                                        (void**) &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


hr = pObjHandle->Unwrap(&v);

_HostProcessRequest *pPR = NULL;
hr = v.pdispVal->QueryInterface(__uuidof(_HostProcessRequest), 
                                (void**) &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",
    // hook up the handler
    ResolveEventHandlertrh= new ResolveEventHandler ( host.TLoadHandler);

    // 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)));


AppDomain appDomain = AppDomain.CreateDomain("MyDomain",

// set our new policy as the domain-level policy

MSDN Magazine Blog

MSDN Magazine Right Rail

14 Top Features of Visual Basic 14: The Q&A
Leading off the feature in the January issue of MSDN Magazine is Lucian Wischik’s fantastic look at Visual Basic .NET 14. As Wischik writes, the newes... More...
Wednesday, Jan 7
Big Start to the New Year at MSDN Magazine
Folks, things are hopping over here at MSDN Magazine. We are kicking off the new year with a pair of issues: Our regularly scheduled January issue and... More...
Friday, Jan 2

More MSDN Magazine Blog entries >

Receive the MSDN Flash e-mail newsletter every other week, with news and information personalized to your interests and areas of focus.