Запуск .NET: различия между версиями

Материал из Etersoft wiki
Перейти к навигацииПерейти к поиску
(Новая страница: «Запуск управляемого кода (.NET C#) из неуправляемого (cpp) Для запуска управляемого кода, нуж…»)
 
 
Строка 1: Строка 1:
Запуск управляемого кода (.NET C#) из неуправляемого (cpp)
Запуск управляемого кода (.NET C#) из неуправляемого (cpp)


Для запуска управляемого кода, нужно запустить .NET машину и передать ей параметры запуска кода. .NET машина выполнена а виде COM объекта и получается с помощью интерфейса IID_ICLRRuntimeHost. (https://msdn.microsoft.com/ru-ru/library/01918c6x(v=vs.110).aspx)  
Для запуска управляемого кода, нужно запустить .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)
Передача параметров для запуска .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
Коды возвратов ExecuteInDefaultAppDomain: http://blogs.msdn.com/b/yizhang/archive/2010/12/17/interpreting-hresults-returned-from-net-clr-0x8013xxxx.aspx




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


Таким образом можно .NET код запускать следующим образом:
Таким образом можно .NET код запускать следующим образом:
CLRCreateInstance( CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost );
CLRCreateInstance( CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost );
pMetaHost->GetRuntime( L"v4.0.30319", IID_ICLRRuntimeInfo, (LPVOID*)&pCLRRuntimeInfo );
pMetaHost->GetRuntime( L"v4.0.30319", IID_ICLRRuntimeInfo, (LPVOID*)&pCLRRuntimeInfo );
pCLRRuntimeInfo->GetInterface( CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&pCLRRuntimeHost );
pCLRRuntimeInfo->GetInterface( CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&pCLRRuntimeHost );
pCLRRuntimeHost->ExecuteInDefaultAppDomain( L"examplelibrary.dll", L"examplelibrary.ClassToLoad", L"methodToLoad", L"", &nRet );
pCLRRuntimeHost->ExecuteInDefaultAppDomain( L"examplelibrary.dll", L"examplelibrary.ClassToLoad", L"methodToLoad", L"", &nRet );


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




В чём проблема:
В чём проблема:
Если посмотреть код CLREventBase::CreateMonitorEvent,  
Если посмотреть код CLREventBase::CreateMonitorEvent,  
synch.cpp
 
void CLREventBase::CreateMonitorEvent(SIZE_T Cookie)
:synch.cpp
...
 
    IHostSyncManager *pManager = CorHost2::GetHostSyncManager();
::void CLREventBase::CreateMonitorEvent(SIZE_T Cookie)
    if (pManager != NULL){
::{
...
:::...
hr = pManager->CreateMonitorEvent(Cookie,&pEvent);
:::IHostSyncManager *pManager = CorHost2::GetHostSyncManager();
...
:::if (pManager != NULL)
else
:::{
{
::::...
HANDLE h = UnsafeCreateEvent(NULL,FALSE,FALSE,NULL);
::::hr = pManager->CreateMonitorEvent(Cookie,&pEvent);
...
::::...
}
:::}
:::else
:::{
::::HANDLE h = UnsafeCreateEvent(NULL,FALSE,FALSE,NULL);
::::...
:::}
:::...
::}
Т.е. При разных вариантах выбираются разные реализации CreateEvent. UnsafeCreateEvent -- это winapi функуция.  
Т.е. При разных вариантах выбираются разные реализации CreateEvent. UnsafeCreateEvent -- это winapi функуция.  
Откуда же берётся IHostSyncManager.  
Откуда же берётся IHostSyncManager.  


А берётся он вот таким образом  
А берётся он вот таким образом  
corhost.cpp
corhost.cpp
HRESULT CorHost2::SetHostControl(IHostControl* pHostControl)
HRESULT CorHost2::SetHostControl(IHostControl* pHostControl)
pHostControl->GetHostManager(IID_IHostSyncManager,(void**)&syncManager) в  
pHostControl->GetHostManager(IID_IHostSyncManager,(void**)&syncManager) в  


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


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


Есть полная реализация IHostControl, вместе с его интерфейсами:
Есть полная реализация IHostControl, вместе с его интерфейсами:
https://github.com/ldematte/HostedPumpkin
https://github.com/ldematte/HostedPumpkin
https://github.com/pwlodek/CodeGallery/tree/master/src/ClrHostingDemo/src/DemoHost3
https://github.com/pwlodek/CodeGallery/tree/master/src/ClrHostingDemo/src/DemoHost3


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

Текущая версия на 19:02, 27 февраля 2015

Запуск управляемого кода (.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 реализован.