Использование неуправляемого кода для проверки наличия среды выполнения .net - PullRequest
2 голосов
/ 06 мая 2011

Я хочу создать смешанную управляемую / неуправляемую DLL, которая может быть загружена rundll32 и которая проверяет наличие библиотеки времени выполнения .Net, прежде чем пытаться запустить любой управляемый код, таким образом:

using namespace System;

void SomeManagedCode()
{
    Diagnostics::Debug::WriteLine("Hello managed code!");
}

#pragma managed(push,off)

bool isRuntimeInstalled()
{
    // check for runtime using some *unmanaged* code

    return true;
}

extern "C" __declspec(dllexport) void _stdcall RunDllEntryPoint(
            HWND hWnd, HINSTANCE hInst, LPSTR lpszCmdLine, int nCmdShow)
{
    if (isRuntimeInstalled())
    {
        SomeManagedCode();
    }
    else
    {
        OutputDebugString(L".net framework not installed");
    }
}

#pragma managed(pop)

Чтобы добиться этого, я попытался /DELAYLOAD CLR (mscoree.dll и т. Д.), Чтобы он загружался только при вызове SomeManagedCode (), а не раньше. Тем не менее, CLR все еще загружается даже до вызова RunDllEntryPoint () (я вижу mscoree.dll в списке загруженных модулей). Я считаю, что это потому, что компилятор связывает в коде, который вызывает _CorDllMain (), который должен принудительно загрузить среду выполнения до вызова моей собственной точки входа.

Я знаю, что есть способы переупаковать это, чтобы оно заработало, например. разделить управляемый код на отдельную DLL, но мне интересно, есть ли способ заставить вышеуказанный код работать в одной DLL.

Возможно ли действительно задержать загрузку библиотек CLR, и если да, то как?

1 Ответ

0 голосов
/ 03 июня 2015

Может ли это быть вызвано вызовом функции SomeManagedCode () в вашей RunDllEntryPoint?Будет ли это исправить ситуацию, добавив слой косвенности?

#pragma managed
void SomeManagedCode()
{
    Diagnostics::Debug::WriteLine("Hello managed code!");
}
#pragma unmanaged
void CallSomeManagedCode()
{
    SomeManagedCode();
}
extern "C" __declspec(dllexport) void _stdcall RunDllEntryPoint(
        HWND hWnd, HINSTANCE hInst, LPSTR lpszCmdLine, int nCmdShow)
{
    if (isRuntimeInstalled())
    {
        CallSomeManagedCode();
    }
    else
    {
        OutputDebugString(L".net framework not installed");
    }
}

Я попал в аналогичную ситуацию, пытаясь предотвратить загрузку .NET из неправильного потока и добавив слои косвенности, то есть никогда не вызывать напрямую.любой управляемый код или управляемые классы из собственной точки входа, я смог оттолкнуть загрузку .NET до позже (в моем случае, пока я не мог сделать это из другого потока).

...