Thread: file version

  1. #1

    file version

    I added a version resource to my file (dll) and I want to read it in that same file. (the version info is ther in explorer so that works I think)
    I'm using "VerQueryValue" but I don't know if this is the best way to do it. I think there must be a better way because its't the same file that contains the resource.

    here's the code I'm using.
    Code:
    DWORD versioninfo_size;
    DWORD buffer;
    	void  *versioninfo;
    	void *data;
    	UINT uint;
    	versioninfo_size=GetFileVersionInfoSize ( "filename.dll", &buffer);
    	GetFileVersionInfo("filename.dll",NULL,versioninfo_size, &versioninfo);
    	VerQueryValue(versioninfo,"\\StringFileInfo\\081304b0\\FileVersion",&data,&uint);
    edit: versioninfo_size gets it size as it should (I think)
    VerQueryValue gives me a unhandled exception.
    could this be that it is because the code is in the same file as the resource???
    I got 081304b0 from the .rc (don't know if I'm allowed to do this)
    What am I doing wrong?

    compiler: MSVC++ 6

    thx

    maes
    Last edited by maes; 07-05-2004 at 02:39 AM.

  2. #2
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    GetFileVersionInfoSize() is a funny api because it actually returns the size. The variable you pass in is simply a dummy that will contain zero on return.

    Once you have the required size, you need to allocate memory to hold the version information resource. Here is something that may work. I haven't tested it, so let me know if it works.

    Code:
    void ShowFileVersion(void)
    {
    	DWORD  versioninfo_size;
    	void*  versioninfo;
    	LPTSTR file_version;
    	UINT   cchLength;
    	DWORD  dwDummy;
    	TCHAR  szModulePath[MAX_PATH];
    	CHAR   szBuf[200];
    
    	/* Get the complete path to the module(DLL or EXE) we are executing in. */
    	if (0 == GetModuleFileName(NULL, szModulePath, MAX_PATH))
    	{
    		return FALSE;
    	}
    
    	/* Get the size of the version information resource in the file. */
    	versioninfo_size = GetFileVersionInfoSize(szModulePath, &dwDummy);
    	if (0 == versioninfo_size)
    	{
    		return FALSE;
    	}
    
    	/* Allocate memory for the version information resource. */
    	versioninfo = malloc(versioninfo_size);
    	if (NULL = versioninfo)
    	{
    		return FALSE;
    	}
    
    	/* Get the version information resource in our buffer. */
    	if (!GetFileVersionInfo(szModulePath, 0, versioninfo_size, versioninfo))
    	{
    		free(versioninfo);
    		return FALSE;
    	}
    
    	/* Get a pointer to the FileVersion string value in file_version. */
    	if (!VerQueryValue(versioninfo,"\\StringFileInfo\\081304b0\\FileVersion", (void **) &file_version, &cchLength) ||
    	    0 == cchLength || NULL == file_version)
    	{
    		free(versioninfo);
    		return FALSE;
    	}
    
    	MessageBox(NULL, file_version, TEXT("File Version"), NULL, 0);
    
    	free(versioninfo);
    	return TRUE;
    }
    Search for "\\StringFileInfo\\040904b0\\FileVersion"(0409 is for English) for more examples.

    P.S I didn't know that Dutch was a language used in Belgium, how many languages does Belgium use!?
    Last edited by anonytmouse; 07-05-2004 at 04:12 AM.

  3. #3
    I forgot to allocate memory Dooooh. I went to a concert last night and I'm probably not awake yet. the usual monday morning sickness I guess

    but your code did the trick. Thx anonytmouse
    I think I'm going to put the resource in english (to make it more bug proof) because as you asked, Belgium is a small country of many languages.
    3 official: Dutch, Frenc, German (only small part but it's an official language)
    and besides that, you need to know english if you want a job (most of the time)
    So I think I'll put it in English to be sure no one changes it to french.

    Thx for the help

  4. #4
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    If needed, you can support multiple languages in your version information:
    Code:
    // Sample version information...
    VS_VERSION_INFO VERSIONINFO
    FILEVERSION    1,0,0,0 // Use this binary version number instead of a localized string - see below
    PRODUCTVERSION 1,0,0,0
    FILEOS         VOS_NT
    FILETYPE       VFT_APP
    {
    BLOCK "StringFileInfo"
    {
    	BLOCK "040904B0"
    	{
    		VALUE "CompanyName", "Company name in English"
    		VALUE "FileDescription", "File description in English"
    		VALUE "FileVersion", "1.0.0.0"
    		// Other values
    	}
    
    	BLOCK "081304B0"
    	{
    		VALUE "CompanyName", "Company name in Belgian Dutch"
    		VALUE "FileDescription", "File description in Belgian Dutch"
    		VALUE "FileVersion", "1.0.0.0"
    		// Other values
    	}
    
    }
    }
    Instead of using a string version, for internal purposes you are probably better off using the binary version number:
    Code:
    void ShowFileVersion(void)
    {
    	DWORD  versioninfo_size;
    	void*  versioninfo;
    	VS_FIXEDFILEINFO * fixed_info;
    	UINT   cbLength;
    	DWORD  dwDummy;
    	TCHAR  szModulePath[MAX_PATH];
    	CHAR   szBuf[200];
    
    	/* Get the complete path to the module(DLL or EXE) we are executing in. */
    	if (0 == GetModuleFileName(NULL, szModulePath, MAX_PATH))
    	{
    		return FALSE;
    	}
    
    	/* Get the size of the version information resource in the file. */
    	versioninfo_size = GetFileVersionInfoSize(szModulePath, &dwDummy);
    	if (0 == versioninfo_size)
    	{
    		return FALSE;
    	}
    
    	/* Allocate memory for the version information resource. */
    	versioninfo = malloc(versioninfo_size);
    	if (NULL = versioninfo)
    	{
    		return FALSE;
    	}
    
    	/* Get the version information resource in our buffer. */
    	if (!GetFileVersionInfo(szModulePath, 0, versioninfo_size, versioninfo))
    	{
    		free(versioninfo);
    		return FALSE;
    	}
    
    	/* Get a pointer to the fixed file version info in fixed_info. */
    	if (!VerQueryValue(versioninfo,"\\", (void **) &fixed_info, &cbLength) ||
    	    cbLength < sizeof(VS_FIXEDFILEINFO) || NULL == fixed_info)
    	{
    		free(versioninfo);
    		return FALSE;
    	}
    
    	/* Use the values in fixed_info. */
    	{
    	  TCHAR buf[256];
    	  wsprintf(buf, TEXT("The version of this file is %d.%d"),
    	                fixed_info->dwFileVersionMS, fixed_info->dwFileVersionLS);
    
    	  MessageBox(NULL, buf, TEXT("File Version"), NULL, 0);
    	}
    
    	free(versioninfo);
    	return TRUE;
    }
    This will also be easier to compare against.

  5. #5
    Registered User
    Join Date
    Sep 2004
    Posts
    124
    A search has just got me here as I'm looking to piuck up the CompanyName in an application I'm working on, but I don't understand the highlighed bit in the following line of code:

    VerQueryValue(versioninfo,"\\StringFileInfo\\081304b0\\FileVersion",&data,&uint);

    What is that number and what is it used for? It looks as though it's something to do with Unicode, and if you want the result in English then that's the number you use.

    Is that correct, or does it serve some other purpose?
    I think you can put a signature here.

  6. #6
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Resurrecting very old threads is frowned upon at Cboard. Typically, you should start a new thread and link back to the old thread.

    As outlined above, the version information may be provided in multiple languages in the one executable. The language number is then used in the query string to indicate which language information you want.

    The first half of the number you have highlighted is the language code (0x0813 is the language code for "Dutch (Belgium)"). You can find a complete list of language codes at MSDN. The second half is the character encoding used to encode the version information (0x04b0 is the code page for "Unicode UCS-2 Little-Endian", which is the default encoding used for version information). You can find a complete list of code pages at MSDN (however, the code page numbers are given in decimal while the version string requires the code page in hexadecimal).

    For US English, the language code is 0x0409. So to retrieve version information in US English (the default), you would use the query string:
    Code:
    \\StringFileInfo\\040904b0\\CompanyName

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. File transfer- the file sometimes not full transferred
    By shu_fei86 in forum C# Programming
    Replies: 13
    Last Post: 03-13-2009, 12:44 PM
  2. sequential file program
    By needhelpbad in forum C Programming
    Replies: 80
    Last Post: 06-08-2008, 01:04 PM
  3. Formatting a text file...
    By dagorsul in forum C Programming
    Replies: 12
    Last Post: 05-02-2008, 03:53 AM
  4. Formatting the contents of a text file
    By dagorsul in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2008, 12:36 PM
  5. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM