如何根据windows版本正确加载GetMappedFileName
How to load GetMappedFileName correctly based on windows version
MSDN的备注部分,描述here,特别提到以下函数的加载类型有区别
由于我的模块是可移植的并且动态加载模型,我不允许/不能使用任何预处理器命令:
#if (PSAPI_VERSION == 2)
(GetProcAddress("kernel32.dll", OBFUSCATE(L"K32GetMappedFileNameW")));
#elif (PSAPI_VERSION == 1)
(GetProcAddress("psapi.dll", OBFUSCATE(L"GetMappedFileNameW")));
#endif
另外 -
Kernel32.dll on Windows 7 and Windows Server 2008 R2; Psapi.dll (if
PSAPI_VERSION=1) on Windows 7 and Windows Server 2008 R2; Psapi.dll on
Windows Server 2008, Windows Vista, Windows Server 2003, and Windows
XP
并没有更清楚地说明 windows 版本与 PSAPI 版本的精确协调。
GetMappedFileName()
documentation具体说:
Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI version number affects the name used to call the function and the library that a program must load.
If PSAPI_VERSION is 2 or greater, this function is defined as K32GetMappedFileName in Psapi.h and exported in Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as GetMappedFileName in Psapi.h and exported in Psapi.lib and Psapi.dll as a wrapper that calls K32GetMappedFileName.
Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function as GetMappedFileName. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and compile the program with -DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll.
如果静态链接不适合您,并且您需要在运行时动态加载函数而不使用 #ifdef
语句,那么只需无条件地检查两个 DLL,例如:
typedef DWORD WINAPI (*LPFN_GetMappedFileNameW)(HANDLE hProcess, LPVOID lpv, LPWSTR lpFilename, DWORD nSize);
HINSTANCE hPsapi = NULL;
LPFN_GetMappedFileNameW lpGetMappedFileNameW = NULL;
...
lpGetMappedFileNameW = (LPFN_GetMappedFileNameW) GetProcAddress(GetModuleHandle("kernel32.dll"), L"K32GetMappedFileNameW"));
if (lpGetMappedFileNameW == NULL)
{
hPsapi = LoadLibraryW(L"psapi.dll");
lpGetMappedFileNameW = (LPFN_GetMappedFileNameW) GetProcAddress(hPsapi, L"GetMappedFileNameW");
}
// use lpGetMappedFileNameW() as needed ...
if (hPsapi)
FreeLibrary(hPsapi);
或者,按照文档中的说明操作 - 完全忽略 kernel32 并在所有 Windows 版本上单独使用 psapi.dll。在 Windows 7 及更高版本中,psapi.GetMappedFileNameW()
是 kernel32.K32GetMappedFileNameW()
.
的包装器
typedef DWORD WINAPI (*LPFN_GetMappedFileNameW)(HANDLE hProcess, LPVOID lpv, LPWSTR lpFilename, DWORD nSize);
HINSTANCE hPsapi = NULL;
LPFN_GetMappedFileNameW lpGetMappedFileNameW = NULL;
...
hPsapi = LoadLibraryW(L"psapi.dll");
lpGetMappedFileNameW = (LPFN_GetMappedFileNameW) GetProcAddress(hPsapi, L"GetMappedFileNameW");
// use lpGetMappedFileNameW() as needed ...
FreeLibrary(hPsapi);
MSDN的备注部分,描述here,特别提到以下函数的加载类型有区别
由于我的模块是可移植的并且动态加载模型,我不允许/不能使用任何预处理器命令:
#if (PSAPI_VERSION == 2)
(GetProcAddress("kernel32.dll", OBFUSCATE(L"K32GetMappedFileNameW")));
#elif (PSAPI_VERSION == 1)
(GetProcAddress("psapi.dll", OBFUSCATE(L"GetMappedFileNameW")));
#endif
另外 -
Kernel32.dll on Windows 7 and Windows Server 2008 R2; Psapi.dll (if PSAPI_VERSION=1) on Windows 7 and Windows Server 2008 R2; Psapi.dll on Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP
并没有更清楚地说明 windows 版本与 PSAPI 版本的精确协调。
GetMappedFileName()
documentation具体说:
Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI version number affects the name used to call the function and the library that a program must load.
If PSAPI_VERSION is 2 or greater, this function is defined as K32GetMappedFileName in Psapi.h and exported in Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as GetMappedFileName in Psapi.h and exported in Psapi.lib and Psapi.dll as a wrapper that calls K32GetMappedFileName.
Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function as GetMappedFileName. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and compile the program with -DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll.
如果静态链接不适合您,并且您需要在运行时动态加载函数而不使用 #ifdef
语句,那么只需无条件地检查两个 DLL,例如:
typedef DWORD WINAPI (*LPFN_GetMappedFileNameW)(HANDLE hProcess, LPVOID lpv, LPWSTR lpFilename, DWORD nSize);
HINSTANCE hPsapi = NULL;
LPFN_GetMappedFileNameW lpGetMappedFileNameW = NULL;
...
lpGetMappedFileNameW = (LPFN_GetMappedFileNameW) GetProcAddress(GetModuleHandle("kernel32.dll"), L"K32GetMappedFileNameW"));
if (lpGetMappedFileNameW == NULL)
{
hPsapi = LoadLibraryW(L"psapi.dll");
lpGetMappedFileNameW = (LPFN_GetMappedFileNameW) GetProcAddress(hPsapi, L"GetMappedFileNameW");
}
// use lpGetMappedFileNameW() as needed ...
if (hPsapi)
FreeLibrary(hPsapi);
或者,按照文档中的说明操作 - 完全忽略 kernel32 并在所有 Windows 版本上单独使用 psapi.dll。在 Windows 7 及更高版本中,psapi.GetMappedFileNameW()
是 kernel32.K32GetMappedFileNameW()
.
typedef DWORD WINAPI (*LPFN_GetMappedFileNameW)(HANDLE hProcess, LPVOID lpv, LPWSTR lpFilename, DWORD nSize);
HINSTANCE hPsapi = NULL;
LPFN_GetMappedFileNameW lpGetMappedFileNameW = NULL;
...
hPsapi = LoadLibraryW(L"psapi.dll");
lpGetMappedFileNameW = (LPFN_GetMappedFileNameW) GetProcAddress(hPsapi, L"GetMappedFileNameW");
// use lpGetMappedFileNameW() as needed ...
FreeLibrary(hPsapi);