Запуск .NET: различия между версиями
(Новая страница: «Запуск управляемого кода (.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 | ||
... | |||
::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 функуция. | Т.е. При разных вариантах выбираются разные реализации 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 реализован.