// Gets the custom AppDomain for loading managed BA. static HRESULT GetAppDomain( __out _AppDomain **ppAppDomain ) { HRESULT hr = S_OK; ICorRuntimeHost *pCLRHost = NULL; IUnknown *pUnk = NULL; LPWSTR sczAppBase = NULL; LPWSTR sczConfigPath = NULL; IAppDomainSetup *pAppDomainSetup; BSTR bstrAppBase = NULL; BSTR bstrConfigPath = NULL; hr = GetAppBase(&sczAppBase); ExitOnFailure(hr, "Failed to get the host base path."); hr = PathConcat(sczAppBase, L"BootstrapperCore.config", &sczConfigPath); ExitOnFailure(hr, "Failed to get the full path to the application configuration file."); // Check that the supported framework is installed. hr = CheckSupportedFrameworks(sczConfigPath); ExitOnFailure(hr, "Failed to find supported framework."); // Load the CLR. hr = GetCLRHost(sczConfigPath, &pCLRHost); ExitOnFailure(hr, "Failed to create the CLR host."); hr = pCLRHost->Start(); ExitOnRootFailure(hr, "Failed to start the CLR host."); // Create the setup information for a new AppDomain to set the app base and config. hr = pCLRHost->CreateDomainSetup(&pUnk); ExitOnRootFailure(hr, "Failed to create the AppDomainSetup object."); hr = pUnk->QueryInterface(__uuidof(IAppDomainSetup), reinterpret_cast<LPVOID*>(&pAppDomainSetup)); ExitOnRootFailure(hr, "Failed to query for the IAppDomainSetup interface."); ReleaseNullObject(pUnk); // Set properties on the AppDomainSetup object. bstrAppBase = ::SysAllocString(sczAppBase); ExitOnNull(bstrAppBase, hr, E_OUTOFMEMORY, "Failed to allocate the application base path for the AppDomainSetup."); hr = pAppDomainSetup->put_ApplicationBase(bstrAppBase); ExitOnRootFailure(hr, "Failed to set the application base path for the AppDomainSetup."); bstrConfigPath = ::SysAllocString(sczConfigPath); ExitOnNull(bstrConfigPath, hr, E_OUTOFMEMORY, "Failed to allocate the application configuration file for the AppDomainSetup."); hr = pAppDomainSetup->put_ConfigurationFile(bstrConfigPath); ExitOnRootFailure(hr, "Failed to set the configuration file path for the AppDomainSetup."); // Create the AppDomain to load the factory type. hr = pCLRHost->CreateDomainEx(L"MBA", pAppDomainSetup, NULL, &pUnk); ExitOnRootFailure(hr, "Failed to create the MBA AppDomain."); hr = pUnk->QueryInterface(__uuidof(_AppDomain), reinterpret_cast<LPVOID*>(ppAppDomain)); ExitOnRootFailure(hr, "Failed to query for the _AppDomain interface."); LExit: ReleaseBSTR(bstrConfigPath); ReleaseBSTR(bstrAppBase); ReleaseStr(sczConfigPath); ReleaseStr(sczAppBase); ReleaseNullObject(pUnk); ReleaseNullObject(pCLRHost); return hr; }
/// <summary> /// Creates a new CLR application domain. /// </summary> /// <param name="hSession">Handle to the installer session, /// used just for logging</param> /// <param name="pHost">Interface to the runtime host where the /// app domain will be created.</param> /// <param name="szName">Name of the app domain to create.</param> /// <param name="szAppBase">Application base directory path, where /// the app domain will look first to load its assemblies.</param> /// <param name="szConfigFile">Optional XML .config file containing any /// configuration for thae app domain.</param> /// <param name="ppAppDomain">Returned app domain interface.</param> /// <returns>True if the app domain was created successfully, false if /// there was some error.</returns> bool CreateAppDomain(MSIHANDLE hSession, ICorRuntimeHost* pHost, const wchar_t* szName, const wchar_t* szAppBase, const wchar_t* szConfigFile, _AppDomain** ppAppDomain) { IUnknown* punkAppDomainSetup = NULL; IAppDomainSetup* pAppDomainSetup = NULL; HRESULT hr = pHost->CreateDomainSetup(&punkAppDomainSetup); if (SUCCEEDED(hr)) { hr = punkAppDomainSetup->QueryInterface(__uuidof(IAppDomainSetup), (void**) &pAppDomainSetup); punkAppDomainSetup->Release(); } if (FAILED(hr)) { Log(hSession, L"Failed to create app domain setup. Error code 0x%X", hr); return false; } const wchar_t* szUrlPrefix = L"file:///"; size_t cchApplicationBase = wcslen(szUrlPrefix) + wcslen(szAppBase); wchar_t* szApplicationBase = (wchar_t*) _alloca((cchApplicationBase + 1) * sizeof(wchar_t)); if (szApplicationBase == NULL) hr = E_OUTOFMEMORY; else { StringCchCopy(szApplicationBase, cchApplicationBase + 1, szUrlPrefix); StringCchCat(szApplicationBase, cchApplicationBase + 1, szAppBase); BSTR bstrApplicationBase = SysAllocString(szApplicationBase); if (bstrApplicationBase == NULL) hr = E_OUTOFMEMORY; else { hr = pAppDomainSetup->put_ApplicationBase(bstrApplicationBase); SysFreeString(bstrApplicationBase); } } if (SUCCEEDED(hr) && szConfigFile != NULL) { BSTR bstrConfigFile = SysAllocString(szConfigFile); if (bstrConfigFile == NULL) hr = E_OUTOFMEMORY; else { hr = pAppDomainSetup->put_ConfigurationFile(bstrConfigFile); SysFreeString(bstrConfigFile); } } if (FAILED(hr)) { Log(hSession, L"Failed to configure app domain setup. Error code 0x%X", hr); pAppDomainSetup->Release(); return false; } IUnknown* punkAppDomain; hr = pHost->CreateDomainEx(szName, pAppDomainSetup, NULL, &punkAppDomain); pAppDomainSetup->Release(); if (SUCCEEDED(hr)) { hr = punkAppDomain->QueryInterface(__uuidof(_AppDomain), (void**) ppAppDomain); punkAppDomain->Release(); } if (FAILED(hr)) { Log(hSession, L"Failed to create app domain. Error code 0x%X", hr); return false; } return true; }