示例#1
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;
}