2011-05-06 59 views
2

我想創建一個混合託管/非託管DLL,可以由rundll32加載,並在嘗試運行任何託管代碼之前檢查是否存在.Net運行時庫,正是如此:使用非託管代碼檢查是否存在.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 dll,如果是這樣,怎麼辦?

回答

0

難道是你的RunDllEntryPoint中觸發它的函數調用「SomeManagedCode()」的存在嗎?它會通過添加一個間接層來解決問題嗎?

#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的加載,直到後來(在我的情況下,直到我可以從不同的線程做到這一點)。

相關問題