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; }