示例#1
0
// 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;
}
示例#2
0
bool CLRHost::LoadInteropLibrary() 
{
    if (!isInitialized) {
        Log(TEXT("CLRHost::LoadInteropLibrary() Runtime not initialized, examine log for cause"));
        return false;
    }

    HRESULT hr;

    IUnknown *appDomainSetupUnknown = NULL;
    IAppDomainSetup *appDomainSetup = NULL;
    IUnknown *appDomainUnknown = NULL;

    bstr_t bstrPluginPath(INTEROP_PATH);
    bstr_t isShadowCopyFiles("true");
    bstr_t interopAssemblyDll(INTEROP_ASSEMBLY);
    bstr_t interopAssemblyName("CLRHost.Interop");

    bstr_t assemblyClassName("CLROBS.API");
    bstr_t pluginClassName("CLROBS.Plugin");
    bstr_t imageSourceTypeName("CLROBS.ImageSource");
    bstr_t imageSourceFactoryTypeName("CLROBS.ImageSourceFactory");
    bstr_t settingsPaneTypeName("CLROBS.SettingsPane");
    bstr_t xElementTypeName("CLROBS.XElement");

    SAFEARRAY *constructorArgs = nullptr;
    SAFEARRAY *apiArgs = nullptr;
    LONG argIndex;
    variant_t clrApiPtr((long long)clrApi);
    variant_t libraryPtr;

    hr = corRuntimeHost->CreateDomainSetup(&appDomainSetupUnknown);
    if (FAILED(hr)) {
        Log(TEXT("ICorRuntimeHost::CreateDomainSetup() failed: 0x%08lx"), hr);
        goto errorCleanup;
    }

    hr = appDomainSetupUnknown->QueryInterface( __uuidof( mscorlib::IAppDomainSetup), (void**)&appDomainSetup);
    if (FAILED(hr)) {
        Log(TEXT("IAppDomainSetup::QueryInterface() failed: 0x%08lx"), hr);
        goto errorCleanup;
    }
    hr = appDomainSetup->put_ApplicationBase(bstrPluginPath);
    if (FAILED(hr)) {
        Log(TEXT("IAppDomainSetup::put_ApplicationBase(%s) failed: 0x%08lx"), INTEROP_PATH, hr);
        goto errorCleanup;
    }
    hr = appDomainSetup->put_ShadowCopyFiles(isShadowCopyFiles);
    if (FAILED(hr)) {
        Log(TEXT("IAppDomainSetup::put_ShadowCopyFiles(%s) failed: 0x%08lx"), TEXT("TRUE"), hr);
        goto errorCleanup;
    }
    hr = appDomainSetup->put_ApplicationName(interopAssemblyDll);
    if (FAILED(hr)) {
        Log(TEXT("IAppDomainSetup::put_ApplicationName(%s) failed: 0x%08lx"), INTEROP_ASSEMBLY, hr);
        goto errorCleanup;
    }
    {
        std::vector<std::wstring> files;
        GetFilesInDirectory(files, INTEROP_PATH TEXT("*"), FILE_ATTRIBUTE_DIRECTORY);
        std::wstring combinedPath;
        for(auto itor = files.begin(); itor < files.end(); itor++)
        {
            if (*itor != TEXT(".") && *itor != TEXT("..")) {
                combinedPath.append(*itor).append(L";");
            }
        }
   
        bstr_t combinedPathString(combinedPath.c_str());
        hr = appDomainSetup->put_PrivateBinPath(combinedPathString);
        if (FAILED(hr)) {
            Log(TEXT("IAppDomainSetup::put_PrivateBinPath(%s) failed: 0x%08lx"), INTEROP_ASSEMBLY, hr);
            goto errorCleanup;
        }
    }

    hr = corRuntimeHost->CreateDomainEx(interopAssemblyDll, appDomainSetup, nullptr, &appDomainUnknown);
    if (FAILED(hr)) {
        Log(TEXT("ICorRuntimeHost::CreateDomainEx(%s, ...) failed: 0x%08lx"), INTEROP_ASSEMBLY, hr);
        goto errorCleanup;
    }

    appDomainSetup->Release();
    appDomainSetup = nullptr;

    hr = appDomainUnknown->QueryInterface(__uuidof( mscorlib::_AppDomain ), (void**)&appDomain);
    if (FAILED(hr)) {
        Log(TEXT("IAppDomain::QueryInterface(%s, ...) failed: 0x%08lx"), hr);
        goto errorCleanup;
    }
    appDomainUnknown->Release();
    appDomainUnknown = nullptr;

    Log(TEXT("CLRHost::LoadInteropLibrary() load the assembly %s"), INTEROP_ASSEMBLY_PATH); 
    hr = appDomain->Load_2(interopAssemblyName, &libraryAssembly);
    if (FAILED(hr)) { 
        Log(TEXT("CLRHost::LoadInteropLibrary() failed to load the assembly: 0x%08lx"), hr); 
        goto errorCleanup;
    }

    hr = libraryAssembly->GetType_2(assemblyClassName, &libraryType);
    if (FAILED(hr)) {
        Log(TEXT("CLRHost::LoadInteropLibrary() failed to get type definition of interop library API class: 0x%08lx"), hr); 
        goto errorCleanup;
    }

    hr = libraryAssembly->GetType_2(pluginClassName, &pluginType);
    if (FAILED(hr)) {
        Log(TEXT("CLRHost::LoadInteropLibrary() failed to get type definition of Plugin class: 0x%08lx"), hr); 
        goto errorCleanup;
    }

    hr = libraryAssembly->GetType_2(imageSourceTypeName, &imageSourceType);
    if (FAILED(hr)) {
        Log(TEXT("CLRHost::LoadInteropLibrary() failed to get type definition of ImageSource class: 0x%08lx"), hr); 
        goto errorCleanup;
    }

    hr = libraryAssembly->GetType_2(imageSourceFactoryTypeName, &imageSourceFactoryType);
    if (FAILED(hr)) {
        Log(TEXT("CLRHost::LoadInteropLibrary() failed to get type definition of ImageSourceFactory class: 0x%08lx"), hr); 
        goto errorCleanup;
    }

    hr = libraryAssembly->GetType_2(settingsPaneTypeName, &settingsPaneType);
    if (FAILED(hr)) {
        Log(TEXT("CLRHost::LoadInteropLibrary() failed to get type definition of SettingsPane class: 0x%08lx"), hr); 
        goto errorCleanup;
    }

    hr = libraryAssembly->GetType_2(xElementTypeName, &xElementType);
    if (FAILED(hr)) {
        Log(TEXT("CLRHost::LoadInteropLibrary() failed to get type definition of XElement class: 0x%08lx"), hr); 
        goto errorCleanup;
    }

    apiArgs = SafeArrayCreateVector(VT_VARIANT, 0, 1);
    argIndex = 0;

    hr = SafeArrayPutElement(apiArgs, &argIndex, &clrApiPtr); 
    if (FAILED(hr)) 
    { 
        wprintf(L"SafeArrayPutElement failed: 0x%08lx", hr); 
        goto errorCleanup; 
    }

    hr = libraryAssembly->CreateInstance_3(assemblyClassName, false, BindingFlags_Default, nullptr, apiArgs, nullptr, nullptr, &libraryPtr);
    if (FAILED(hr) || !libraryPtr.punkVal) {
        Log(TEXT("CLRHost::LoadInteropLibrary() failed to instantiate our interop library class: 0x%08lx"), hr); 
        goto errorCleanup;
    }

    libraryInstance = libraryPtr.punkVal;
    libraryInstance->AddRef();


    SafeArrayDestroy(apiArgs);
    apiArgs = nullptr;

    isLibraryLoaded = true;
    goto success;

errorCleanup:
    if (appDomainSetup) {
        appDomainSetup->Release();
        appDomainSetup = nullptr;
    }
    if (appDomainUnknown) {
        appDomainUnknown->Release();
        appDomainUnknown = nullptr;
    }
    if (appDomain) {
        appDomain->Release();
        appDomain = nullptr;
    }
    if (libraryAssembly) {
        libraryAssembly->Release();
        libraryAssembly = nullptr;
    }
    if (libraryType) {
        libraryType->Release();
        libraryType = nullptr;
    }
    if (imageSourceType) {
        imageSourceType->Release();
        imageSourceType = nullptr;
    }
    if (imageSourceFactoryType) {
        imageSourceFactoryType->Release();
        imageSourceFactoryType = nullptr;
    }
    if (settingsPaneType) {
        settingsPaneType->Release();
        settingsPaneType = nullptr;
    }
    if (xElementType) {
        xElementType->Release();
        xElementType = nullptr;
    }
    if (apiArgs) {
        SafeArrayDestroy(apiArgs);
    }

    return false;
success:
    return true;
}
示例#3
0
文件: ClrHost.cpp 项目: BMurri/wix3
/// <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;
}