Метод запуска ICLRRuntimeHost никогда не возвращается

Я внедряю неуправляемую DLL в другой неуправляемый процесс. Цель здесь - использовать этот загрузчик для инициализации CLR, чтобы я мог использовать.NET Framework в целевом процессе. Инъекция работает нормально, однако попытки запустить CLR и загрузить мою управляемую библиотеку вызывают у меня проблемы. Вот мой код, с которым я пытаюсь запустить CLR (вызывается прямо из DLLMain):

void Init() {
    ICLRRuntimeHost *pClrHost = NULL;
    HRESULT hr = CorBindToRuntimeEx(NULL, L"wks", 0, CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (PVOID*)&pClrHost);

    MessageBox(NULL, L"attempt start", L"Dll", MB_OK);
    hr = pClrHost->Start();
    MessageBox(NULL, L"past start", L"Dll", MB_OK);

    DWORD dwRet = 0;
    hr = pClrHost->ExecuteInDefaultAppDomain(L"C:\\Users\\Blank\\Documents\\ManagedLibrary.dll", L"Namespace.Class", L"Main", L"Parameters", &dwRet);
}

Мое первое окно сообщения появляется нормально, но вызов Start() кажется заблокированным и никогда не возвращается. Это приводит к тому, что целевой процесс перестает отвечать на запросы. Комментирование Start() и попытка немедленного выполнения дает идентичный результат.

1 ответ

Решение

Я пытаюсь запустить CLR (вызывается прямо из DLLMain)

Вы не можете запустить CLR изнутри DllMain, DllMain это очень враждебное место, где вы, в принципе, не можете сделать много вещей без проблем из-за того, что (глобальная) блокировка загрузчика удерживается, пока код выполняется внутри DllMain, В вашем примере, скорее всего, ICLRRuntimeHost.Start() пытается сделать что-то, что также захочет заблокировать эту блокировку загрузчика и, таким образом, блокировать (взаимоблокировки). Вы должны увидеть это с помощью отладчика.

Раймонд Чен (oldnewthing) написал пару постов в блоге об этом и связанных с ним проблемах, например, об этом.

Другие вопросы по тегам