C++获取dll自身模块路径的几种方法
第一种:
首先在dllmain中保存HMODULE句柄,然后使用GetModuleFileName(HMODULE) 获取,这是一个比较简单直接的方案,但是dll如果内存加载(也就是dllmain无法被正确调用的时候)就无法使用了。
第二种:
通过GetModuleHandleEx传入dll的名称获取其HMODULE,然后再通过GetModuleFileName获取路径。但是当多个装载的模块具有相同的基本名称和扩展名时,GetModuleHandleEx无法预测返回哪个模块的句柄:https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulehandleexa
HMODULE hModule = nullptr; ::GetModuleHandleEx(0, L"dllModuleName", &hModule);
第三种:
通过函数地址获取其模块句柄,然后通过GetModuleFileName传入模块句柄获取。通过地址获取模块路径又有两种方法,分别如下:
方法1
HMODULE GetSelfModuleHandle() { MEMORY_BASIC_INFORMATION mbi; if (::VirtualQuery(GetSelfModuleHandle, &mbi, sizeof(mbi)) == 0) return nullptr; return (HMODULE)mbi.AllocationBase; }
方法2
HMODULE hModule = nullptr; ::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)&TestFunction, &hModule);
第四种:
通过__ImageBase获取
extern "C" IMAGE_DOS_HEADER __ImageBase; int main() { wchar_t szPath[MAX_PATH] = { 0 }; ::GetModuleFileName((HMODULE)&__ImageBase, szPath, MAX_PATH); return 0; }