.NET 4 doesn't allow us to catch "corrupted state exceptions" by default which is real pain when writing in-process stuff. Good thing is that we can re-enable it - either globally with app.config or HandleProcessCorruptedStateExceptionsAttribute.
Source: HANDLING CORRUPTED STATE EXCEPTIONS
HandleProcessCorruptedStateExceptionsAttribute works fine, but I'd like to enable it globally. The app.config works on standard application, but I'm unable to load app.config in injected assembly.
My clr startup code
Code:
CComPtr<ICLRMetaHostPolicy> pMetaHostPolicy = NULL;
CComPtr<ICLRRuntimeInfo> pRuntimeInfo = NULL;
CComPtr<ICorRuntimeHost> pRuntimeHost = NULL;
CComPtr<IUnknown> pAppDomainSetupUnk;
CComPtr<IAppDomainSetup> pAppDomainSetup;
CComPtr<IUnknown> pAppDomainUnk;
CComPtr<_AppDomain> pAppDomain;
HRCHK( CoInitialize( NULL ) );
HMODULE loaderModule = GetModuleHandle( L"DotNetLoader.dll" );
if ( loaderModule == NULL )
throw std::string( "Failed to locate loader module" );
TCHAR moduleName[ 1024 ];
if ( !GetModuleFileName( loaderModule, moduleName, 1024 ) )
throw std::string( "Failed to retrieve module name" );
std::wstring loaderFullPath = moduleName;
std::wstring libFile = L"Bsus.exe";
std::wstring libDir = std::wstring( moduleName ).substr( 0, loaderFullPath.find_last_of( L"\\" ) );
std::wstring libFullPath = std::wstring( libDir ).append( L"\\" ).append( libFile );
std::wstring libConfig = std::wstring( libFullPath ).append( L".config" );
DWORD retVal = 0;
HRCHK( CLRCreateInstance( CLSID_CLRMetaHostPolicy, IID_ICLRMetaHostPolicy, (LPVOID*)&pMetaHostPolicy ) );
DWORD pcchVersion = 0;
DWORD dwConfigFlags = 0;
HRCHK( pMetaHostPolicy->GetRequestedRuntime( METAHOST_POLICY_HIGHCOMPAT,
libFullPath.c_str(), NULL,
NULL, &pcchVersion,
NULL, NULL, &dwConfigFlags,
IID_ICLRRuntimeInfo,
(LPVOID*)&pRuntimeInfo ) );
HRCHK( pRuntimeInfo->BindAsLegacyV2Runtime() );
HRCHK( pRuntimeInfo->GetInterface( CLSID_CorRuntimeHost, IID_ICorRuntimeHost, (LPVOID*) &pRuntimeHost ) );
HRCHK( pRuntimeHost->Start() );
HRCHK( pRuntimeHost->CreateDomainSetup( &pAppDomainSetupUnk ) );
HRCHK( pAppDomainSetupUnk->QueryInterface( __uuidof(IAppDomainSetup), (void**)&pAppDomainSetup ) );
HRCHK( pAppDomainSetup->put_ApplicationBase( CComBSTR( libDir.c_str() ) ) );
HRCHK( pAppDomainSetup->put_ConfigurationFile( CComBSTR( libConfig.c_str() ) ) );
HRCHK( pRuntimeHost->CreateDomainEx( L"Bsus", pAppDomainSetup, NULL, &pAppDomainUnk ) );
HRCHK( pAppDomainUnk->QueryInterface( __uuidof(_AppDomain), (void**)&pAppDomain ) );
HRCHK( pAppDomain->ExecuteAssembly_2( CComBSTR( libFullPath.c_str() ), NULL ) );
pRuntimeHost->UnloadDomain( pAppDomain );
FreeLibraryAndExitThread( loaderModule, 0 );
As you can see I'm creating new domain and executing assembly in it. I can get configuration path later AppDomain.CurrentDomain.SetupInformation.ConfigurationFile but corrupt state exceptions are still not handled. If I put invalid content into app.config, it doesn't complain or anything - standart executable refuses to run with invalid app.config. Any idea how to make AppDomain load app.config?