The entry point GetFileVersionInfoSizeEx
-
I was working in Windows Vista, and I moved the project over to XP to create the setup and deployment program. I guess on the XP, I have some small details to fix. At first I thought it was just a Vista thing, I looked up the function, at it is Vista and up. Not sure how to proceed on this, looking for suggestions. Is there a way to use the ex and non ex version of the function, and to somehow keep them seperate?
-
I was working in Windows Vista, and I moved the project over to XP to create the setup and deployment program. I guess on the XP, I have some small details to fix. At first I thought it was just a Vista thing, I looked up the function, at it is Vista and up. Not sure how to proceed on this, looking for suggestions. Is there a way to use the ex and non ex version of the function, and to somehow keep them seperate?
You can check the version of the OS, and for XP, use the non-ex version. Then for Vista and above, use GetProcAddress()[^] to dynamically link to the ex version at run time.
The difficult we do right away... ...the impossible takes slightly longer.
-
You can check the version of the OS, and for XP, use the non-ex version. Then for Vista and above, use GetProcAddress()[^] to dynamically link to the ex version at run time.
The difficult we do right away... ...the impossible takes slightly longer.
-
Actually is not as easy as it looks. Unless you really need to retrieve localized version info size, use GetFileVersionInfoSize instead GetFileVersionInfoSizeEx. GetFileVersionInfoSize is available starting with Windows 2000. You do not have to call LoadLibrary and GetProcAddress since your module (exe) is linked implicitly with Version.lib. To write robust code you would have to write more than simple GetProcAddress. If you really want to use both, depending on the operating system, you will have to retrieve proc address depending on OS version and load appropriate procedure address, since Version.lib contains both: ASCII and UNICODE versions of the functions. If your app is built as ANSII you would have to use ANSI version of the function: GetFileVersionInfoSizeExW or GetFileVersionInfoSizeW depending on what system your app is running on. For unicode build you will have to explicitly request UNICODE versions: GetFileVersionInfoSizeExW or GetFileVersionInfoSizeA. Something like this:
//#define _USE_EXPLICIT
void GetFileVersionLenInfo()
{
OSVERSIONINFO osvi = {sizeof(OSVERSIONINFO)};
DWORD dwHandle = 8000;
DWORD dwVer = 0;
GetVersionEx(&osvi);
HINSTANCE hInst = NULL;#ifdef _USE_EXPLICIT
typedef DWORD (CALLBACK\* lpfnGETFILEVERSIONINFOSIZEEX)(DWORD, LPCTSTR, LPDWORD); typedef DWORD (CALLBACK\* lpfnGETFILEVERSIONINFOSIZE)(LPCTSTR, LPDWORD); //typedef UINT (CALLBACK\* LPFNDLLFUNC1)(DWORD,UINT); hInst = LoadLibrary(\_T("VERSION.dll")); if(osvi.dwMajorVersion > 5) {
#ifdef UNICODE
lpfnGETFILEVERSIONINFOSIZEEX lpfnGetFileVersionInfoSizeEx = (lpfnGETFILEVERSIONINFOSIZEEX)GetProcAddress(hInst, "GetFileVersionInfoSizeExW");
#else
lpfnGETFILEVERSIONINFOSIZEEX lpfnGetFileVersionInfoSizeEx = (lpfnGETFILEVERSIONINFOSIZEEX)GetProcAddress(hInst, "GetFileVersionInfoSizeExA");
#endif // UNICODEdwVer = lpfnGetFileVersionInfoSizeEx(FILE\_VER\_GET\_NEUTRAL, \_T("C:\\\\Program Files\\\\Beyond Compare 2\\\\BC2.exe"), &dwHandle); return; }
#ifdef UNICODE
lpfnGETFILEVERSIONINFOSIZE lpfnGetFileVersionInfoSize = (lpfnGETFILEVERSIONINFOSIZE)GetProcAddress(hInst, "GetFileVersionInfoSizeW");
#else
lpfnGETFILEVERSIONINFOSIZE lpfnGetFileVersionInfoSize = (lpfnGETFILEVERSIONINFOSIZE)GetProcAddress(hInst, "GetFileVersionInfoSizeA");
#endif // UNICODE
dwVer = lpfnGetFileVersionInfoSize(
_T("C:\\Program Files\\Beyond Compare 2\\BC2.exe"),
&dwHandle);#else
dwVer = GetFileVersionInfoSize(
_T("C:\\Program Files\\Beyond Compare 2\\BC22.exe"), -
Actually is not as easy as it looks. Unless you really need to retrieve localized version info size, use GetFileVersionInfoSize instead GetFileVersionInfoSizeEx. GetFileVersionInfoSize is available starting with Windows 2000. You do not have to call LoadLibrary and GetProcAddress since your module (exe) is linked implicitly with Version.lib. To write robust code you would have to write more than simple GetProcAddress. If you really want to use both, depending on the operating system, you will have to retrieve proc address depending on OS version and load appropriate procedure address, since Version.lib contains both: ASCII and UNICODE versions of the functions. If your app is built as ANSII you would have to use ANSI version of the function: GetFileVersionInfoSizeExW or GetFileVersionInfoSizeW depending on what system your app is running on. For unicode build you will have to explicitly request UNICODE versions: GetFileVersionInfoSizeExW or GetFileVersionInfoSizeA. Something like this:
//#define _USE_EXPLICIT
void GetFileVersionLenInfo()
{
OSVERSIONINFO osvi = {sizeof(OSVERSIONINFO)};
DWORD dwHandle = 8000;
DWORD dwVer = 0;
GetVersionEx(&osvi);
HINSTANCE hInst = NULL;#ifdef _USE_EXPLICIT
typedef DWORD (CALLBACK\* lpfnGETFILEVERSIONINFOSIZEEX)(DWORD, LPCTSTR, LPDWORD); typedef DWORD (CALLBACK\* lpfnGETFILEVERSIONINFOSIZE)(LPCTSTR, LPDWORD); //typedef UINT (CALLBACK\* LPFNDLLFUNC1)(DWORD,UINT); hInst = LoadLibrary(\_T("VERSION.dll")); if(osvi.dwMajorVersion > 5) {
#ifdef UNICODE
lpfnGETFILEVERSIONINFOSIZEEX lpfnGetFileVersionInfoSizeEx = (lpfnGETFILEVERSIONINFOSIZEEX)GetProcAddress(hInst, "GetFileVersionInfoSizeExW");
#else
lpfnGETFILEVERSIONINFOSIZEEX lpfnGetFileVersionInfoSizeEx = (lpfnGETFILEVERSIONINFOSIZEEX)GetProcAddress(hInst, "GetFileVersionInfoSizeExA");
#endif // UNICODEdwVer = lpfnGetFileVersionInfoSizeEx(FILE\_VER\_GET\_NEUTRAL, \_T("C:\\\\Program Files\\\\Beyond Compare 2\\\\BC2.exe"), &dwHandle); return; }
#ifdef UNICODE
lpfnGETFILEVERSIONINFOSIZE lpfnGetFileVersionInfoSize = (lpfnGETFILEVERSIONINFOSIZE)GetProcAddress(hInst, "GetFileVersionInfoSizeW");
#else
lpfnGETFILEVERSIONINFOSIZE lpfnGetFileVersionInfoSize = (lpfnGETFILEVERSIONINFOSIZE)GetProcAddress(hInst, "GetFileVersionInfoSizeA");
#endif // UNICODE
dwVer = lpfnGetFileVersionInfoSize(
_T("C:\\Program Files\\Beyond Compare 2\\BC2.exe"),
&dwHandle);#else
dwVer = GetFileVersionInfoSize(
_T("C:\\Program Files\\Beyond Compare 2\\BC22.exe"),I changed to the non ex version for now, turns out I have a lot of errors to fix in my program to run in XP nice and smooth. I haven't written all the code for the GetFileVersionInfo yet, I have to package the program first, post it on the internet, and then go back and finish the code. Give me a couple of days to experiment with your post, so I can comment on it. But thanks for the extra help.
-
I changed to the non ex version for now, turns out I have a lot of errors to fix in my program to run in XP nice and smooth. I haven't written all the code for the GetFileVersionInfo yet, I have to package the program first, post it on the internet, and then go back and finish the code. Give me a couple of days to experiment with your post, so I can comment on it. But thanks for the extra help.
Another thing to check: Is your project using targetver.h? If yes, change constants to define 0x0500 to target Windows XP. If not, make sure you define WINVER, _WIN32_WINNT and _WIN32_WINDOWS as 0x500 in stdafx.h before any include. Compiler will then flag all errors coming from usage of the functions that are not defined in XP.
JohnCz
-
Another thing to check: Is your project using targetver.h? If yes, change constants to define 0x0500 to target Windows XP. If not, make sure you define WINVER, _WIN32_WINNT and _WIN32_WINDOWS as 0x500 in stdafx.h before any include. Compiler will then flag all errors coming from usage of the functions that are not defined in XP.
JohnCz
Yes, the wizard included it in my stdafx.h, and rc file. So I should do a temp 0x500 to make all the XP errors surface? I think it was just the 4 functions, when I moved the project to vista to make sure that it worked, and worked all the UAC stuff. Then I moved it back to XP just to make sure all was good, and to build my deployment project. stdafx.h
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>// TODO: reference additional headers your program requires here
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") -
Yes, the wizard included it in my stdafx.h, and rc file. So I should do a temp 0x500 to make all the XP errors surface? I think it was just the 4 functions, when I moved the project to vista to make sure that it worked, and worked all the UAC stuff. Then I moved it back to XP just to make sure all was good, and to build my deployment project. stdafx.h
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>// TODO: reference additional headers your program requires here
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")That is not guaranteed. It may also depend on SDK version you are using for build. Compiler will flag errors if header files contain #ifdef with specific versions of windows around some functions to exclude definition for certain versions of Windows. So, you may have some help in finding out what is excluded for XP but you may still be left with some unknowns to resolve on your own.
JohnCz
-
That is not guaranteed. It may also depend on SDK version you are using for build. Compiler will flag errors if header files contain #ifdef with specific versions of windows around some functions to exclude definition for certain versions of Windows. So, you may have some help in finding out what is excluded for XP but you may still be left with some unknowns to resolve on your own.
JohnCz