Я пытаюсь получить зависимости от приложений/библиотек .net из обычной с++ программы. Понятно, что зависимости pe получаются из директорий - там находится mscoree.dll, но так же я хочу получить зависимости сборки. Они есть в манифесте, их видно в dotPeek. Я смог получить список сборок от которых зависит файл .net с помощью вот такой программы (целевая платформа у меня пока win10 и .net 4.0): Код (Text): CComPtr<ICLRMetaHost> pMetaHost; CComPtr<ICLRRuntimeInfo> pRuntime; CComPtr<IMetaDataDispenser> pDisp; CComPtr<IMetaDataAssemblyImport> pAssImport; HRESULT hr = CLRCreateInstance(CLSID_CLRMetaHost,IID_ICLRMetaHost,(void **)&pMetaHost); wchar_t fileVersion[MAX_PATH] = {}; DWORD dwBuffer = MAX_PATH; hr = pMetaHost->GetVersionFromFile(file.c_str(),fileVersion,&dwBuffer); hr = pMetaHost->GetRuntime(fileVersion,IID_ICLRRuntimeInfo,(void **)&pRuntime); hr = pRuntime->GetInterface(CLSID_CorMetaDataDispenser,IID_IMetaDataDispenser,(void **)&pDisp); hr = pDisp->OpenScope(file.c_str(), ofRead, IID_IMetaDataAssemblyImport, reinterpret_cast<IUnknown **>(&pAssImport)); mdAssemblyRef Files[50] = { 0 }; ULONG numTokensOut = 0; ULONG numTokensIn = 50; HCORENUM hCoreEnum = NULL; hr = pAssImport->EnumAssemblyRefs(&hCoreEnum, Files, numTokensIn, &numTokensOut); for (ULONG j = 0; j < numTokensOut; ++j) { wchar_t publicKey[MAX_PATH]; ULONG ulPublicKeyLen; wchar_t simpleName[MAX_PATH]; ULONG ulSimpleName; ASSEMBLYMETADATA assmd{}; wchar_t hash[MAX_PATH]; ULONG ulHash = MAX_PATH; DWORD dwAssemblyRefFlags; hr = pAssImport->GetAssemblyRefProps(Files[j], (const void**)&publicKey, &ulPublicKeyLen, simpleName, MAX_PATH, &ulSimpleName, &assmd, (const void**)&hash, &ulHash,&dwAssemblyRefFlags); } if (hCoreEnum) pAssImport->CloseEnum(hCoreEnum); Её результатом являются имена сборок - System, System.Drawing и т.д. Дальше надо соотнести эти имена с конкретными файлами. Файлы сборок .net хранятся в C:\Windows\Assembly в нескольких каталогах по фреймворку и по битности. И на моей машине файлов System.ni.dll(который является сборкой System) 4 штуки. Я решил попробовать использовать IMetaDataAssemblyImport::FindAssembliesByName для поиска подходящей зависимости, но тут возникли проблемы: в описании функции указано, , который является устаревшим и я использовал его замену - ICLRRuntimeHost::Start. И добавил к коду фрагмент запуска CLR Код (C): CComPtr<ICLRRuntimeHost> pRuntimeHost; hr = pRuntime->GetInterface(CLSID_CorRuntimeHost, IID_ICorRuntimeHost, (LPVOID *)&pRuntimeHost); hr = pRuntimeHost->Start(); Но при выполнении метода Start() происходит исключение И как с ним справиться я пока не знаю. Может кто-то может подсказать другой способ найти конкретные файлы сборок? Мне кажется, что запускать CLR для этого не самый лучший выход. Или какое то обходное решение?
Насчет конкретной проблемы - я не в курсе, но посмотри https://github.com/LADSoft/DotNetPELib - возможно, там есть необходимый тебе функционал.
Огромное спасибо, там в проекте речь о другом, но все же навело меня на дополнительные мысли. Спасибо. Я написал автору, возможно он еще информации добавит.