Setting Host Policy in appdomain

Due to popular demand, I am posting an example how to set host policy in appdomain.

(If you don’t know what host policy is, please refer to the following two blogs:


Assembly Binding Policy

The only way to set host policy is through CLR hosting API.

There are four CLR hosting APIs defined in mscoree.idl in .Net framework SDK.

#pragma midl_echo(“STDAPI CorBindToRuntimeHost(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, LPCWSTR pwszHostConfigFile, VOID* pReserved, DWORD startupFlags, REFCLSID rclsid, REFIID riid, LPVOID FAR *ppv);”)
#pragma midl_echo(“STDAPI CorBindToRuntimeEx(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, DWORD startupFlags, REFCLSID rclsid, REFIID riid, LPVOID FAR *ppv);”)
#pragma midl_echo(“STDAPI CorBindToRuntimeByCfg(IStream* pCfgStream, DWORD reserved, DWORD startupFlags, REFCLSID rclsid,REFIID riid, LPVOID FAR* ppv);”)
#pragma midl_echo(“STDAPI CorBindToRuntime(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, REFCLSID rclsid, REFIID riid, LPVOID FAR *ppv);”)

The only one can set host policy is CorBindToRuntimeHost. The host policy is set automatically in every appdomain.

Documentation for CLR hosting interface can be found at

The example below hosts CLR, then executes a managed application in default appdomain. The managed application simply loads an assembly to demostrate that host policy is applied.

E:\demo>more hostdemo.cpp
#include “windows.h”
#include “stdio.h”
#include “mscoree.h”

#import  <mscorlib.tlb> raw_interfaces_only high_property_prefixes(“_get”,”_put”,”_putref”)

using namespace mscorlib;

int wmain(int argc, WCHAR **argv)
    if (argc != 3) {
        printf(“Usage: HostDemo HostConfigFile AppToExecute\n”);
        return 1;

    ICorRuntimeHost *pHost = NULL;
    IUnknown *pAppDomainThunk = NULL;
        _AppDomain *pAppDomain = NULL;

    // let’s host CLR
    HRESULT hr = CorBindToRuntimeHost(  L”v1.1.4322″,   // pwzVersion
                                L”wks”,   // pwzBuildFlavor
                                argv[1],  // host config file
                                NULL,   // reversed
                                0,      // startup flag,

    if (FAILED(hr)) {
        printf(“CorBindToRuntimeHost failed with hr=0x%x.\n”, hr);
        return 2;

    // Start the runtime
    hr = pHost->Start();
    if (FAILED(hr)) {
        printf(“ICorRuntimeHost->Start failed with hr=0x%x.\n”, hr);
        return 3;

    // Get the default appdomain.
    hr = pHost->GetDefaultDomain(&pAppDomainThunk);
    if (FAILED(hr)) {
        printf(“ICorRuntimeHost->GetDefaultDomain failed with hr=0x%x.\n”, hr);
        return 4;

    // Get System::_AppDomain interface
    hr = pAppDomainThunk->QueryInterface(__uuidof(_AppDomain),
                                        (void**) &pAppDomain);
    if (FAILED(hr)) {
        printf(“Can’t get System::_AppDomain interface\n”);
        return 5;

    long lRet= 0;
    // call System::_AppDomain::ExecuteAssembly(String)
    hr = pAppDomain->ExecuteAssembly_2(_bstr_t(argv[2]), &lRet);
    if (FAILED(hr)) {
        printf(“_AppDomain::ExecuteAssembly_2 failed with hr=0x%x.\n”, hr);
        return 6;

    return 0;

E:\demo>more hello.cs
using System;
using System.Reflection;

public class test
    public static void Main()
        Console.WriteLine(Assembly.Load(“test, version=, culture=neutral, publickeytoken=ba6def5dd8a8ddac”).Location);

E:\demo>more test.cs
using System;
using System.Reflection;

public class test
    public String WhoAmI()
        return “Test.dll”;

E:\demo>more build.bat
cl hostdemo.cpp mscoree.lib
csc hello.cs
csc /t:library test.cs
move test.dll c:\temp\test.dll

E:\demo>more example.config
      <assemblyBinding xmlns=”urn:schemas-microsoft-com:asm.v1″>
            <assemblyIdentity name=”test”
                              culture=”neutral” />
            <bindingRedirect oldVersion=”″ newVersion=”″/>
            <codeBase version=”″ href=”c:\temp\test.dll”/>


E:\demo>cl hostdemo.cpp mscoree.lib
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80×86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

Microsoft (R) Incremental Linker Version 7.10.3077
Copyright (C) Microsoft Corporation.  All rights reserved.


E:\demo>csc hello.cs
Microsoft (R) Visual C# .NET Compiler version 7.10.6001.4
for Microsoft (R) .NET Framework version 1.1.4322
Copyright (C) Microsoft Corporation 2001-2002. All rights reserved.
E:\demo>csc /t:library test.cs
Microsoft (R) Visual C# .NET Compiler version 7.10.6001.4
for Microsoft (R) .NET Framework version 1.1.4322
Copyright (C) Microsoft Corporation 2001-2002. All rights reserved.

E:\demo>move test.dll c:\temp\test.dll
        1 file(s) moved.

E:\demo>hostdemo example.config hello.exe

Due to the restriction of codebase in host policy, I have to use a bogus redirect in example.config to make sure the codebase is picked up correctly.

The example is compiled with VS.Net 2003, and run under .Net framework 1.1.

Comments (10)

  1. Carl Daniel [VC++ MVP] says:

    That #import is a bit obscure, since the HTML ate your <MSCORLIB.TLB>.

    You mentioned that ASP.NET no longer uses host poilicy in Whidbey – is support for host policy still supported in the CLR? Is it deprecated?

  2. Thanks for pointing out. Yes, <mscorlib.tlb> is missing.

    The host policy is still in Whidbey. ASP.Net still reserves the right to use it. It just won’t use it by default.

  3. Thanks for that! BTW, it looks like your URLs have got mangled somewhere along the way. They all start with "http://blogs/juzhang/&quot;.

    You mention, "a bogus redirect in example.config to make sure the codebase is picked up correctly". I’m guessing the codeBase version can’t lie about what version it is redirecting to. It would complain if the ‘test.dll’ at ‘c:temptest.dll’ was in actual fact version ‘’?

    <codeBase version="" href="c:temptest.dll"/>

    Thanks! Jamie.

  4. Jamie,

    That is not what I mean. I am referring to the restriction of codebase hint in host config, namely, you can’t take a codebase hint without taking a real binding redirect. That is why even my test.dll has a version number of, I load version in hello.cs, and use host config to redirect to so that codebase hint can be honored.

    Please read for more detail on this.

    Basically, It probably means you can’t use it for the purpose you described in

  5. You mention in the artile you refer to, "We will honor the codebase hint in machine.config, even there is no assembly binding redirect". Is there any reason why you’re not bringing the ‘Host Policy’ rules in line with ‘machine.config’?

    Thanks for sharing this stuff with us. It is a complex topic and I really appreciate someone getting this information out there!

    Here’s an idea for a future post. "Why no User GAC?" In the same way that the registry has user and machine hives, the GAC could be similarly split. I’m sure this must have been discussed. I’m curious to know why it was decided against.

    Thanks, Jamie.

  6. Good question.

    Basically it is a customer demand thing.

    ASP.Net is our only customer using host policy. Since they are removing host policy, we have no request for that. So we did not make the change.

    If we see more people start request this, we may make the change. Right now it is unlikely it will be in Whidbey.

  7. David Levine says:

    Add me to the list of people requesting the change to always honor a codebase hint. 🙂 I’m not so concerned about host policy – I’m more concerned about how it affects assemblies in the GAC. This is one of those quirky requirements that is likely to create a lot of confusion.

    Have you any documentation on the precedence of evaluation of host policy versus other policies? If the policies conflict (e.g. different redirects or codebases for the same assembly) which one gets used?

    Thanks as always.

  8. Mattias says:

    I have some problems with loading a UserConrol in its own domain. It’s described in this link.

  9. Mattias,

    How is your problem related to host policy?