03-27-2011 09:56 PM
Who can help me to get the below version information? Thanks.
Does CVI have a function for reading this version information?
03-27-2011 11:48 PM - edited 03-27-2011 11:49 PM
Hi Vicent, this is not possible with native CVI functions: you must use SDK calls instead:
//--------------------------------------------------------------------------
//
// Function FileVersion
//
//--------------------------------------------------------------------------
/// HIFN FileVersion
/// HIFN Function to retrieve version informations from the .exe
/// HIRET Error code - '0' means OK
/// HIPAR file/Pathname of the executable to query
/// HIPAR version/String where to store version informations
int CVIFUNC FileVersion (char *file, char *version)
{
void* tempBuffer = NULL;
void* versionInfo = NULL;
int error = 0;
char dummy[64], langName[16];
UINT len;
DWORD infoSize;
DWORD uselessParm;
DWORD* tempDWORD;
if ((infoSize = GetFileVersionInfoSize (file, &uselessParm))) {
nullChk (versionInfo = malloc (infoSize));
if (!GetFileVersionInfo (file, 0, infoSize, versionInfo))
goto Error;
/* Get the Language and Code Page */
/* The below 'hex' value looks a little confusing, but essentially */
/* it is the hexidecimal representation of a couple different values */
/* that represent the language and character set that we are wanting */
/* string values for. 040904E4 is very common, it means: */
/* US English, Windows MultiLingual characterset -- or: */
/* 04------ = SUBLANG_ENGLISH_USA */
/* --09---- = LANG_ENGLISH */
/* --11---- = LANG_JAPANESE */
/* ----04E4 = 1252 = Codepage for Windows:Multilingual */
if (VerQueryValue (versionInfo, TEXT("\\VarFileInfo\\Translation"),
((void **)(&tempDWORD)), &len)) {
/* lVerPointer is a pointer to four 4 bytes of Hex number, first two */
/* bytes are language id, and last two bytes are code page. However, */
/* Lang_Charset_String needs a string of 4 hex digits, the first two */
/* characters correspond to the language id and last two the last two*/
/* character correspond to the code page id. */
langName[0] = 0;
sprintf (langName, "%04hX%04hX", LOWORD (*tempDWORD),
HIWORD (*tempDWORD));
if (langName[0]) {
sprintf (dummy, "\\StringFileInfo\\%s\\ProductVersion", langName);
if (!VerQueryValue (versionInfo, TEXT (dummy), &tempBuffer, &len) == 0)
if (tempBuffer)
strcpy (version, (char *)tempBuffer);
}
}
}
Error:
if (versionInfo) free (versionInfo);
return error;
}
Actual returned string won't have the '+' embedded in the originating string.
03-28-2011 04:29 AM
Thanks, Roberto.
Can you tell which .h file should be included for the GetFileVersionInfoSize function?
03-28-2011 04:40 AM - edited 03-28-2011 04:40 AM
Necessary declarations are listed in the Win SDK (called Win32API in newer versions of CVI). I normally include windows.h as I make use of other APIs: it may be that a specific, smaller include is enough for this function. I forgot to mention that you need to add version.lib to your project.
03-28-2011 07:17 AM - edited 03-28-2011 07:18 AM
For the avoidance of doubt, the code quoted in Roberto's posting actually retrieves the Text Information version of the Product Version, not the Numeric Information version. These can, of course, be different.
03-28-2011 07:39 AM
You're right, Martin: the information retrieved is part of the text section of the panel; I don't think the numeric information can be retrieved 'as is', since wnhen you build the executable CVI calculates actual value for each string and embeds the result in the executable; the result of translation can be seen by checking Preview Substitutions checkbox at the bottom of that panel.
Version info can be tailored as you want: as an example, we normally don't use all 4 fields in the file version, and I put in the corresponding field in 'text information' section the string "Version %1 (build %2)", which results in a string embedded like "Version 1 (build 3)" that can be retrieved in this form with the code I posted as well as seen in the file properties dialog box in Windows Explorer.
03-28-2011 08:43 AM
Roberto:
As it happens, you can retrieve the numeric Product Version, which is stored as part of the version info:
//-------------------------------------------------------------------------- // // Function FileVersion (Alternate)
// //-------------------------------------------------------------------------- /// HIFN FileVersion /// HIFN Function to retrieve version informations from the .exe /// HIRET Error code - '0' means OK /// HIPAR file/Pathname of the executable to query /// HIPAR version/String where to store version informations int CVIFUNC FileVersion (char *file, char *version) { void* versionInfo = NULL; int error = 0; UINT len; DWORD infoSize; DWORD uselessParm; VS_FIXEDFILEINFO* fixedVerInfoPtr; if ((infoSize = GetFileVersionInfoSize (file, &uselessParm))) { nullChk (versionInfo = malloc (infoSize)); if (!GetFileVersionInfo (file, 0, infoSize, versionInfo)) goto Error; if (!VerQueryValue (versionInfo, TEXT("\\"), (void **)&fixedVerInfoPtr, &len)) goto Error; /* Get the Product Version */ sprintf (version, "%d.%d.%d.%d", (fixedVerInfoPtr->dwProductVersionMS & 0xffff0000) >> 16, (fixedVerInfoPtr->dwProductVersionMS & 0xffff), (fixedVerInfoPtr->dwProductVersionLS & 0xffff0000) >> 16, (fixedVerInfoPtr->dwProductVersionLS & 0xffff)); } Error: if (versionInfo) free (versionInfo); return error; }
It's always numeric (of course), and is useful therefore for doing numeric comparisons of version - you can put dwProductVersionMS & dwProductVersionLS together as a single 64 bit integer.
03-28-2011 08:43 AM
Vincent,
If you are using CVI 2010, you can use the predefined macro _TARGET_PRODUCT_VERSION_ as a string in your program. There is also a macro for the file version, _TARGET_FILE_VERSION_. Each time your program is compiled these macros will be updated to the current values in the Version Info dialog.
Michael
NI
03-28-2011 09:54 PM
Thanks all of you.
Your method works well in my program.
Thanks again.
By the way, Micheal, I am using CVI9.0, I didn't find macro _TARGET_PRODUCT_VERSION_ in the help files. Is it only for CVI2010?
03-28-2011 11:57 PM
Vicent,
I'm happy you have somved your problem!
Martin,
thanks for your suggestion: when I looked for those functions I was interested to strings but it's good to know how to retrieve version informations in numeric format. I'll bookmark your post for future use.
Michael,
I'm using CVI2009 at present but I'll keep your post bookmarked to retrieve it when I'll switch to 2010.