tag renamer online mp3tag mp3meta mp3id c++ windows winapi windows-7 windows-xp

c++ - renamer - Cómo cargar GetMappedFileName correctamente según la versión de Windows



tag rename (1)

La sección de observaciones de MSDN, descrita aquí , menciona específicamente que existe una diferencia entre los tipos de carga de la siguiente función.

Como mi módulo es portátil y carga modelos dinámicamente, no puedo / puedo usar ningún comando de preprocesador:

#if (PSAPI_VERSION == 2) (GetProcAddress("kernel32.dll", OBFUSCATE(L"K32GetMappedFileNameW"))); #elif (PSAPI_VERSION == 1) (GetProcAddress("psapi.dll", OBFUSCATE(L"GetMappedFileNameW"))); #endif

En adición -

Kernel32.dll en Windows 7 y Windows Server 2008 R2; Psapi.dll (si PSAPI_VERSION = 1) en Windows 7 y Windows Server 2008 R2; Psapi.dll en Windows Server 2008, Windows Vista, Windows Server 2003 y Windows XP

No deja mucho más claro cómo la versión de Windows está coordinada exactamente con la versión de PSAPI.


La documentación de GetMappedFileName() dice específicamente:

Comenzando con Windows 7 y Windows Server 2008 R2, Psapi.h establece números de versión para las funciones de PSAPI. El número de versión de PSAPI afecta el nombre utilizado para llamar a la función y la biblioteca que debe cargar un programa .

Si PSAPI_VERSION es 2 o mayor, esta función se define como K32GetMappedFileName en Psapi.h y se exporta en Kernel32.lib y Kernel32.dll . Si PSAPI_VERSION es 1, esta función se define como GetMappedFileName en Psapi.h y se exporta en Psapi.lib y Psapi.dll como un contenedor que llama a K32GetMappedFileName .

Los programas que deben ejecutarse en versiones anteriores de Windows y en Windows 7 y versiones posteriores siempre deben llamar a esta función como GetMappedFileName. Para garantizar la resolución correcta de los símbolos, agregue Psapi.lib a la macro TARGETLIBS y compile el programa con -DPSAPI_VERSION = 1. Para usar el enlace dinámico en tiempo de ejecución, cargue Psapi.dll.

Si la vinculación estática no es una opción para usted, y necesita cargar dinámicamente la función en tiempo de ejecución sin utilizar sentencias #ifdef , simplemente verifique ambas DLL incondicionalmente, por ejemplo:

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);

O simplemente haga lo que dice la documentación: simplemente ignore kernel32 por completo y simplemente use psapi.dll por sí mismo en todas las versiones de Windows. En Windows 7 y psapi.GetMappedFileNameW() posteriores, psapi.GetMappedFileNameW() es un contenedor para 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);