WINAPI 編程擷取檔案版本資訊
cheungmine
本文示範如何使用win32 api 編寫獲得檔案描述和產品版本。很簡單的小程式。下面就是全部代碼:test.c
//<br />// test.c<br />// by cheungmine<br />//<br />#include <windows.h><br />#include <stdio.h><br />#define DLLFILE "C://WINDOWS//system32//aaaamon.dll"<br />//<br />// 使用 WIN32 API 取得檔案的描述和版本資訊<br />//<br />void GetFileDescriptionAndProductVersionA(LPCSTR lpstrFilename,<br />LPSTR lpoutFileDescription, UINT cbDescSize,<br />LPSTR lpoutProductVersion, UINT cbVerSize)<br />{<br />typedef DWORD(WINAPI *pfnGetFileVersionInfoSizeA)(LPCSTR,LPDWORD);<br />typedef BOOL(WINAPI *pfnGetFileVersionInfoA)(LPCSTR,DWORD,DWORD,LPVOID);<br />typedef BOOL(WINAPI *pfnVerQueryValueA)(const LPVOID,LPCSTR,LPVOID*,PUINT);<br />HMODULE hDll = 0;<br />DWORD dwHandle=0;<br />DWORD dwInfoSize=0;<br />pfnGetFileVersionInfoSizeA fnGetFileVersionInfoSizeA = 0;<br />pfnGetFileVersionInfoA fnGetFileVersionInfoA = 0;<br />pfnVerQueryValueA fnVerQueryValueA = 0;</p><p>*lpoutFileDescription = 0;<br />*lpoutProductVersion = 0;</p><p>// Load system32/version.dll module<br />hDll = LoadLibraryA("version.dll");<br />if (!hDll)<br />return;</p><p>fnGetFileVersionInfoSizeA = (pfnGetFileVersionInfoSizeA) GetProcAddress(hDll, "GetFileVersionInfoSizeA");<br />fnGetFileVersionInfoA = (pfnGetFileVersionInfoA) GetProcAddress(hDll, "GetFileVersionInfoA");<br />fnVerQueryValueA = (pfnVerQueryValueA) GetProcAddress(hDll, "VerQueryValueA");<br />// If failed to get procdure address<br />if (!fnGetFileVersionInfoSizeA || !fnGetFileVersionInfoA || !fnVerQueryValueA){<br />FreeLibrary(hDll);<br />return;<br />}<br />dwInfoSize = fnGetFileVersionInfoSizeA(lpstrFilename, &dwHandle);</p><p>if (dwInfoSize > 0){<br />void *pvInfo = malloc(dwInfoSize);<br />if (!pvInfo)<br />exit(-1);// Out of memory<br />if (fnGetFileVersionInfoA(lpstrFilename, 0, dwInfoSize, pvInfo)){<br />struct LANGANDCODEPAGE {<br />WORD wLanguage;<br />WORD wCodePage;<br />} *lpTranslate;</p><p>// Read the list of languages and code pages.<br />UINT cbTranslate = 0;</p><p>if ( fnVerQueryValueA(pvInfo, "//VarFileInfo//Translation", (void**) &lpTranslate, &cbTranslate) ){<br />// ONLY Read the file description for FIRST language and code page.<br />if ((cbTranslate/sizeof(struct LANGANDCODEPAGE)) > 0){<br />const char *lpBuffer=0;<br />UINT cbSizeBuf = 0;<br />char szSubBlock[50];</p><p>// Retrieve file description for language and code page 0<br />wsprintfA(szSubBlock, "//StringFileInfo//%04x%04x//FileDescription", lpTranslate[0].wLanguage, lpTranslate[0].wCodePage);<br />if ( fnVerQueryValueA(pvInfo, szSubBlock, (void**)&lpBuffer, &cbSizeBuf) ){<br />//warning4996: strncpy(lpoutFileDescription, lpBuffer, cbDescSize-1);<br />strncpy_s(lpoutFileDescription, cbDescSize, lpBuffer, cbDescSize-1);<br />lpoutFileDescription[cbDescSize-1] = 0;<br />}<br />// Retrieve file version for language and code page 0<br />wsprintfA(szSubBlock, "//StringFileInfo//%04x%04x//ProductVersion", lpTranslate[0].wLanguage, lpTranslate[0].wCodePage);<br />if ( fnVerQueryValueA(pvInfo, szSubBlock, (void**)&lpBuffer, &cbSizeBuf) ){<br />//warning4996: strncpy(lpoutProductVersion, lpBuffer, cbVerSize-1);<br />strncpy_s(lpoutProductVersion, cbVerSize, lpBuffer, cbVerSize-1);<br />lpoutProductVersion[cbVerSize-1] = 0;<br />}<br />// Retrieve others for language and code page 0 if you like<br />// ...<br />}<br />}<br />}<br />// Free memory<br />free(pvInfo);<br />}<br />// Free mudule<br />FreeLibrary(hDll);<br />}<br />int main(int argc, char* argv[])<br />{<br />char szFileDesc[128];<br />char szProductVersion[32];</p><p>GetFileDescriptionAndProductVersionA(DLLFILE, szFileDesc, 128, szProductVersion, 32);<br />printf("源檔案:%s/n檔案描述:%s/n產品版本:%s", DLLFILE, szFileDesc, szProductVersion);</p><p>getchar();<br />return 0;<br />}<br />