Get DLL path at runtime

前端 未结 10 1329
梦谈多话
梦谈多话 2020-11-28 22:31

I want to get a dll\'s directory (or file) path from within its code. (not the program\'s .exe file path)

I\'ve tried a few methods I\'ve found:

相关标签:
10条回答
  • 2020-11-28 23:06

    Provided you implemented the following dll entry point: (usually dllmain.cpp)

    BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
    

    You can simply do:

    switch (ul_reason_for_call)
    { 
    case DLL_PROCESS_ATTACH:
    {
        TCHAR dllFilePath[512 + 1] = { 0 };
        GetModuleFileNameA(hModule, dllFilePath, 512)
    }
        break;
    case DLL_THREAD_ATTACH: break;
    ...
    

    dllFilePath will then contain the path to where the current dll code was loaded. In this case hModule is passed by the process loading the dll.

    0 讨论(0)
  • 2020-11-28 23:07

    You can use the GetModuleHandleEx function and get the handle to a static function in your DLL. You'll find more information here.

    After that you can use GetModuleFileName to get the path from the handle you just obtained. More information on that call is here.

    A complete example:

    char path[MAX_PATH];
    HMODULE hm = NULL;
    
    if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | 
            GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
            (LPCSTR) &functionInThisDll, &hm) == 0)
    {
        int ret = GetLastError();
        fprintf(stderr, "GetModuleHandle failed, error = %d\n", ret);
        // Return or however you want to handle an error.
    }
    if (GetModuleFileName(hm, path, sizeof(path)) == 0)
    {
        int ret = GetLastError();
        fprintf(stderr, "GetModuleFileName failed, error = %d\n", ret);
        // Return or however you want to handle an error.
    }
    
    // The path variable should now contain the full filepath for this DLL.
    
    0 讨论(0)
  • 2020-11-28 23:09

    Here's a Unicode, revised version of the top voted answer:

    CStringW thisDllDirPath()
    {
        CStringW thisPath = L"";
        WCHAR path[MAX_PATH];
        HMODULE hm;
        if( GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | 
                                GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
                                (LPWSTR) &thisDllDirPath, &hm ) )
        {
            GetModuleFileNameW( hm, path, sizeof(path) );
            PathRemoveFileSpecW( path );
            thisPath = CStringW( path );
            if( !thisPath.IsEmpty() && 
                thisPath.GetAt( thisPath.GetLength()-1 ) != '\\' ) 
                thisPath += L"\\";
        }
        else if( _DEBUG ) std::wcout << L"GetModuleHandle Error: " << GetLastError() << std::endl;
    
        if( _DEBUG ) std::wcout << L"thisDllDirPath: [" << CStringW::PCXSTR( thisPath ) << L"]" << std::endl;       
        return thisPath;
    }
    
    0 讨论(0)
  • 2020-11-28 23:10

    Try GetModuleFileName function.

    0 讨论(0)
  • 2020-11-28 23:11

    For Delphi users:

    SysUtils.GetModuleName(hInstance);              //Works; hInstance is a special global variable
    SysUtils.GetModuleName(0);                      //Fails; returns the name of the host exe process
    SysUtils.GetModuleName(GetModuleFilename(nil)); //Fails; returns the name of the host exe process
    

    In case your Delphi doesn't have SysUtils.GetModuleName, it is declared as:

    function GetModuleName(Module: HMODULE): string;
    var
       modName: array[0..32767] of Char; //MAX_PATH is for a single filename; paths can be up to 32767 in NTFS - or longer.
    begin
       {
          Retrieves the fully qualified path for the file that contains the specified module. 
          The module must have been loaded by the current process.
       }
       SetString(Result, modName, GetModuleFileName(Module, modName, Length(modName)));
    end;
    
    0 讨论(0)
  • 2020-11-28 23:15
    EXTERN_C IMAGE_DOS_HEADER __ImageBase;
    

    ....

    TCHAR   DllPath[MAX_PATH] = {0};
    GetModuleFileName((HINSTANCE)&__ImageBase, DllPath, _countof(DllPath));
    
    0 讨论(0)
提交回复
热议问题