2

Referencing to this answer I'm trying to get ProductVersion with windows Api using GetFileVersionInfo method. The problem is that through the propreties of .exe ProductVersion is visible, but programmatically I get only "0.0.0.0".

.exe propreties:

exe propreties

output:

output:

Code:

                printf( "File Version 1: %d.%d.%d.%d\n",
                    ( verInfo->dwFileVersionMS >> 16 ) & 0xffff,
                    ( verInfo->dwFileVersionMS >>  0 ) & 0xffff,
                    ( verInfo->dwFileVersionLS >> 16 ) & 0xffff,
                    ( verInfo->dwFileVersionLS >>  0 ) & 0xffff
                    );

                printf( "File Version 2: %d.%d.%d.%d\n",
                    ( verInfo->dwFileVersionLS >> 24 ) & 0xff,
                    ( verInfo->dwFileVersionLS >> 16 ) & 0xff,
                    ( verInfo->dwFileVersionLS >>  8 ) & 0xff,
                    ( verInfo->dwFileVersionLS >>  0 ) & 0xff
                    );


                printf( "Product Version 1: %d.%d.%d.%d\n",
                    ( verInfo->dwProductVersionLS >> 24 ) & 0xff,
                    ( verInfo->dwProductVersionLS >> 16 ) & 0xff,
                    ( verInfo->dwProductVersionLS >>  8 ) & 0xff,
                    ( verInfo->dwProductVersionLS >>  0 ) & 0xff
                    );

                printf( "Product Version 2: %d.%d.%d.%d\n",
                    (verInfo->dwProductVersionMS >> 16) & 0xffff,
                    (verInfo->dwProductVersionMS >>  0) & 0xffff,
                    (verInfo->dwProductVersionLS >> 16) & 0xffff,
                    (verInfo->dwProductVersionLS >>  0) & 0xffff
                    );

                printf( "Product Version 3: %d.%d.%d.%d\n",
                    (verInfo->dwProductVersionMS >> 16) & 0xffff,
                    (verInfo->dwProductVersionMS >>  8) & 0xffff,
                    (verInfo->dwProductVersionLS >> 16) & 0xffff,
                    (verInfo->dwProductVersionLS >>  8) & 0xffff
                    );

The question is - WTF? How to get ProductVersion, and how do the guys from Microsoft did that?

Artiom
  • 538
  • 12
  • 25
  • 3
    Possible duplicate of [How do I read from a version resource in Visual C++](https://stackoverflow.com/questions/316626/how-do-i-read-from-a-version-resource-in-visual-c). What you are looking for is the `ProductVersion` from the language specific (or neutral) `StringFileInfo`. – Christian.K Aug 04 '17 at 10:48
  • 2
    What you see in the dialog is only the string section. But relevant for an update or installer are DWORDs in the VERSIONINFO section – xMRi Aug 04 '17 at 11:05
  • 1
    BTW, only "File Version 1" and "Product Version 2" in your code is correct. The others use incorrect shiftings. Each component of the version number is 16-bit, `dwProductVersionMS` and `dwProductVersionLS` each store two components. – zett42 Aug 04 '17 at 20:04

3 Answers3

2

this worked on my end

   fwprintf(f_output, L"// File Version:\t\t\t%d.%d.%d.%d\n",
        (verInfo->dwFileVersionMS >> 16) & 0xffff,
        (verInfo->dwFileVersionMS >> 0) & 0xffff,
        (verInfo->dwFileVersionLS >> 16) & 0xffff,
        (verInfo->dwFileVersionLS >> 0) & 0xffff
    );
    fwprintf(f_output, L"// Product Version:\t\t\t%d.%d.%d.%d\n",
        (verInfo->dwProductVersionMS >> 16) & 0xffff,
        (verInfo->dwProductVersionMS >> 0) & 0xffff,
        (verInfo->dwProductVersionLS >> 16) & 0xffff,
        (verInfo->dwProductVersionLS >> 0) & 0xffff
    );
BigChief
  • 1,413
  • 4
  • 24
  • 37
1

The version info resource contains a small fixed portion (VS_FIXEDFILEINFO) and optionally some strings.

Some applications display the numbers from the fixed portion and some use the FileVersion/ProductVersion strings.

You should probably use the string if it is present because it allows the developer to add extra pieces of information like Alpha/Beta etc. and because some people forget to properly set the correct version in the fixed part.

Use the VerQueryValue function to get a list of languages and the strings...

Anders
  • 97,548
  • 12
  • 110
  • 164
  • 2
    _You should probably use the string if it is present_ ... that depends on the use case. If you only want to replicate what the properties dialog shows, use the string version. If you need to compare the version of two files, you should always use the fixed info, because that is what installers use. – zett42 Aug 04 '17 at 19:59
  • @zett42 Even Microsoft has forgotten to update the fixed version number a couple of times (in WMP IIRC), the string is more likely to be correct (but more work to parse of course). – Anders Aug 04 '17 at 20:03
  • 2
    A good application should show the whole information contained in the version resource (e. g. Total Commander "file info" plugin does a good job in this regard). But regarding installers, you should only rely on the fixed file info. If the developer of the file does it wrong, it's not the job of the installer to guess what the "real" file version is. – zett42 Aug 04 '17 at 20:09
  • @Anders, yes, I will mark your answer as a right one, thanks for the tip. Didn't know that there are any extra strings. There I found the ProductVersion and that's really strange that VS_FIXEDFILEINFO doesn't contains this info for such a big product .. – Artiom Aug 08 '17 at 11:32
  • Which way microsoft's property dialog uses to display product version? From resource string or from fixed portion? – Mayur Sep 14 '21 at 12:18
0

Here is the code snippet for those who also trying to get the ProductVersion:

if (!VerQueryValue (lpData, TEXT("\\StringFileInfo\\040904E4\\ProductVersion"),
        (LPVOID) &lpBuffer, (PUINT) &BufLen)) {
    /* language ID 040904E4: U.S. English, char set = Windows, Multilingual */
    printf ("ProductVersion:       not found\n");
}
else
    printf ("ProductVersion:       %s\n", lpBuffer);

Here is Full Code.

Artiom
  • 538
  • 12
  • 25