我想创建一个可以由rundll32加载的混合托管/非托管DLL,并在尝试运行任何托管代码之前检查.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() 而不是之前加载它。但是,即使在调用 RunDllEntryPoint() 之前仍会加载 CLR(我可以在加载的模块列表中看到 mscoree.dll)。我相信这是因为编译器正在链接调用 _CorDllMain() 的代码,它必须在调用我自己的入口点之前强制加载运行时。
我知道有一些方法可以重新打包它以使其工作,例如将托管代码拆分为单独的 DLL,但如果有任何方法可以在单个 DLL 中制作上述工作代码,我很感兴趣。
是否有可能真正延迟加载 CLR dll,如果可以,怎么做?