Запуск .NET

Материал из Etersoft wiki
Перейти к: навигация, поиск

Запуск управляемого кода (.NET C#) из неуправляемого (cpp)


Для запуска управляемого кода, нужно запустить .NET машину и передать ей параметры запуска кода. .NET машина выполнена а виде COM объекта и получается с помощью интерфейса IID_ICLRRuntimeHost. (https://msdn.microsoft.com/ru-ru/library/01918c6x(v=vs.110).aspx)

Передача параметров для запуска .NET приложениея просходит с помощью метода ICLRRuntimeHost::ExecuteInDefaultAppDomain, куда передаются имя файла имя класса и метода для запуска. Метод должен быть с такой сигнатурой: public static int methodToLoad(String param). При этом при обычном запуске .NET приложения запускается private static void Main(string[] args). И с помощью ExecuteInDefaultAppDomain его не запустить(https://msdn.microsoft.com/ru-ru/library/ms164411(v=vs.110).aspx)

Коды возвратов ExecuteInDefaultAppDomain: http://blogs.msdn.com/b/yizhang/archive/2010/12/17/interpreting-hresults-returned-from-net-clr-0x8013xxxx.aspx


ICLRMetaHost Предоставляет методы для определения, какие версии CLR установлены,

ICLRRuntimeHost Предоставляет методы, позволяющие основному приложению явным образом запускать и останавливать выполнение среды CLR для создания и настройки доменов приложения с целью доступа к домену по умолчанию и перечисления всех доменов, выполняемых в процессе. C дополнительным методом, позволяющим задать интерфейс управления основным приложением.

IHostControl Предоставляет методы для настройки загрузки сборок и определения интерфейсов размещения, поддерживаемых основным приложением. (DomainManager)

AppDomain -- изолированное окружение для запуска приложений


Таким образом можно .NET код запускать следующим образом:

CLRCreateInstance( CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost );

pMetaHost->GetRuntime( L"v4.0.30319", IID_ICLRRuntimeInfo, (LPVOID*)&pCLRRuntimeInfo );

pCLRRuntimeInfo->GetInterface( CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&pCLRRuntimeHost );

pCLRRuntimeHost->ExecuteInDefaultAppDomain( L"examplelibrary.dll", L"examplelibrary.ClassToLoad", L"methodToLoad", L"", &nRet );


У pCLRRuntimeHost можно получить CLRControl

pCLRRuntimeHost->GetCLRControl(&pCLRControl);

У которого есть методы для получения интерфейсов для мониторинга процессов CLR https://msdn.microsoft.com/ru-ru/library/ms164354(v=vs.110).aspx. Например ICLRDebugManager.



В чём проблема:

Если посмотреть код CLREventBase::CreateMonitorEvent,

synch.cpp
void CLREventBase::CreateMonitorEvent(SIZE_T Cookie)
{
...
IHostSyncManager *pManager = CorHost2::GetHostSyncManager();
if (pManager != NULL)
{
...
hr = pManager->CreateMonitorEvent(Cookie,&pEvent);
...
}
else
{
HANDLE h = UnsafeCreateEvent(NULL,FALSE,FALSE,NULL);
...
}
...
}

Т.е. При разных вариантах выбираются разные реализации CreateEvent. UnsafeCreateEvent -- это winapi функуция.

Откуда же берётся IHostSyncManager.


А берётся он вот таким образом

corhost.cpp

HRESULT CorHost2::SetHostControl(IHostControl* pHostControl)

pHostControl->GetHostManager(IID_IHostSyncManager,(void**)&syncManager) в


CorHost2 судя по всему -- это реализация IID_ICLRRuntimeHost2. MSDN, правда рассказывает только про IID_ICLRRuntimeHost, думаю, что работают они примерно одинаково.


Я не нашёл как же получить реализацию IHostControl в Windows. При этом она есть, например, у такого проекта -- https://code.google.com/p/hadesmem/ (Хешировщик),


Есть полная реализация IHostControl, вместе с его интерфейсами:

https://github.com/ldematte/HostedPumpkin

https://github.com/pwlodek/CodeGallery/tree/master/src/ClrHostingDemo/src/DemoHost3


Я не уверен, что IHostControl в Windows реализован.