Как получить зависимости .net приложений?

Тема в разделе "WASM.WIN32", создана пользователем drem1lin, 13 авг 2020.

Метки:
  1. drem1lin

    drem1lin Member

    Публикаций:
    0
    Регистрация:
    17 мар 2009
    Сообщения:
    300
    Я пытаюсь получить зависимости от приложений/библиотек .net из обычной с++ программы. Понятно, что зависимости pe получаются из директорий - там находится mscoree.dll, но так же я хочу получить зависимости сборки. Они есть в манифесте, их видно в dotPeek. Я смог получить список сборок от которых зависит файл .net с помощью вот такой программы (целевая платформа у меня пока win10 и .net 4.0):
    Код (Text):
    1. CComPtr<ICLRMetaHost> pMetaHost;
    2. CComPtr<ICLRRuntimeInfo> pRuntime;
    3. CComPtr<IMetaDataDispenser> pDisp;
    4. CComPtr<IMetaDataAssemblyImport> pAssImport;
    5.  
    6. HRESULT hr = CLRCreateInstance(CLSID_CLRMetaHost,IID_ICLRMetaHost,(void **)&pMetaHost);
    7.  
    8. wchar_t fileVersion[MAX_PATH] = {};
    9. DWORD dwBuffer = MAX_PATH;
    10. hr = pMetaHost->GetVersionFromFile(file.c_str(),fileVersion,&dwBuffer);
    11.  
    12. hr = pMetaHost->GetRuntime(fileVersion,IID_ICLRRuntimeInfo,(void **)&pRuntime);
    13.  
    14. hr = pRuntime->GetInterface(CLSID_CorMetaDataDispenser,IID_IMetaDataDispenser,(void **)&pDisp);
    15.  
    16. hr = pDisp->OpenScope(file.c_str(), ofRead, IID_IMetaDataAssemblyImport, reinterpret_cast<IUnknown **>(&pAssImport));
    17.  
    18. mdAssemblyRef  Files[50] = { 0 };
    19. ULONG numTokensOut = 0;
    20. ULONG numTokensIn = 50;
    21. HCORENUM hCoreEnum = NULL;
    22.  
    23. hr = pAssImport->EnumAssemblyRefs(&hCoreEnum, Files, numTokensIn, &numTokensOut);
    24.  
    25. for (ULONG j = 0; j < numTokensOut; ++j) {
    26.     wchar_t publicKey[MAX_PATH];
    27.     ULONG ulPublicKeyLen;
    28.     wchar_t simpleName[MAX_PATH];
    29.     ULONG ulSimpleName;
    30.     ASSEMBLYMETADATA assmd{};
    31.     wchar_t hash[MAX_PATH];
    32.     ULONG ulHash = MAX_PATH;
    33.     DWORD dwAssemblyRefFlags;
    34.  
    35.     hr = pAssImport->GetAssemblyRefProps(Files[j], (const void**)&publicKey, &ulPublicKeyLen, simpleName, MAX_PATH, &ulSimpleName, &assmd, (const void**)&hash, &ulHash,&dwAssemblyRefFlags);
    36. }
    37. if (hCoreEnum)
    38.     pAssImport->CloseEnum(hCoreEnum);
    Её результатом являются имена сборок - System, System.Drawing и т.д. Дальше надо соотнести эти имена с конкретными файлами. Файлы сборок .net хранятся в C:\Windows\Assembly в нескольких каталогах по фреймворку и по битности. И на моей машине файлов System.ni.dll(который является сборкой System) 4 штуки.
    Я решил попробовать использовать IMetaDataAssemblyImport::FindAssembliesByName для поиска подходящей зависимости, но тут возникли проблемы: в описании функции указано,
    , который является устаревшим и я использовал его замену - ICLRRuntimeHost::Start.
    И добавил к коду фрагмент запуска CLR

    Код (C):
    1. CComPtr<ICLRRuntimeHost> pRuntimeHost;  
    2. hr = pRuntime->GetInterface(CLSID_CorRuntimeHost, IID_ICorRuntimeHost, (LPVOID *)&pRuntimeHost);
    3.  
    4. hr = pRuntimeHost->Start();
    Но при выполнении метода Start() происходит исключение
    И как с ним справиться я пока не знаю. Может кто-то может подсказать другой способ найти конкретные файлы сборок? Мне кажется, что запускать CLR для этого не самый лучший выход. Или какое то обходное решение?
     
  2. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    Насчет конкретной проблемы - я не в курсе, но посмотри https://github.com/LADSoft/DotNetPELib - возможно, там есть необходимый тебе функционал.
     
    drem1lin нравится это.
  3. drem1lin

    drem1lin Member

    Публикаций:
    0
    Регистрация:
    17 мар 2009
    Сообщения:
    300
    Огромное спасибо, там в проекте речь о другом, но все же навело меня на дополнительные мысли. Спасибо. Я написал автору, возможно он еще информации добавит.