I need to get the product version and file version for a DLL or EXE file using Win32 native APIs in C or C++. I'm not looking for the Windows version, but the version numbers that you see by right-clicking on a DLL file, selecting "Properties", then looking at the "Details" tab. This is usually a four-part dotted version number x.x.x.x.
- 
                    Which language are you using? – overslacked Jun 02 '09 at 17:12
- 
                    7Doesn't matter if he just wants Win32 API calls. Any language that supports calling system DLLs should be fine. – crashmstr Jun 02 '09 at 17:15
- 
                    Edited to clarify that this is about C/C++. – JSBձոգչ Jun 02 '09 at 17:27
- 
                    [GetFileVersionInfo()](http://msdn.microsoft.com/en-us/library/ms647003(VS.85).aspx) – Matt Schmidt Jun 02 '09 at 17:13
6 Answers
You would use the GetFileVersionInfo API.
See Using Version Information on the MSDN site.
Sample:
DWORD  verHandle = 0;
UINT   size      = 0;
LPBYTE lpBuffer  = NULL;
DWORD  verSize   = GetFileVersionInfoSize( szVersionFile, &verHandle);
if (verSize != NULL)
{
    LPSTR verData = new char[verSize];
    if (GetFileVersionInfo( szVersionFile, verHandle, verSize, verData))
    {
        if (VerQueryValue(verData,"\\",(VOID FAR* FAR*)&lpBuffer,&size))
        {
            if (size)
            {
                VS_FIXEDFILEINFO *verInfo = (VS_FIXEDFILEINFO *)lpBuffer;
                if (verInfo->dwSignature == 0xfeef04bd)
                {
                    // Doesn't matter if you are on 32 bit or 64 bit,
                    // DWORD is always 32 bits, so first two revision numbers
                    // come from dwFileVersionMS, last two come from dwFileVersionLS
                    TRACE( "File Version: %d.%d.%d.%d\n",
                    ( verInfo->dwFileVersionMS >> 16 ) & 0xffff,
                    ( verInfo->dwFileVersionMS >>  0 ) & 0xffff,
                    ( verInfo->dwFileVersionLS >> 16 ) & 0xffff,
                    ( verInfo->dwFileVersionLS >>  0 ) & 0xffff
                    );
                }
            }
        }
    }
    delete[] verData;
}
 
    
    - 28,043
- 9
- 61
- 79
- 
                    2`int revision = HIWORD(verInfo->dwProductVersionLS); int build = LOWORD(verInfo->dwProductVersionLS);` – Igor Jerosimić Dec 02 '13 at 23:49
- 
                    8I know it has been a while, but for newbies like me this is how you get the .exe filename: `TCHAR szVersionFile[MAX_PATH]; GetModuleFileName(NULL, szVersionFile, MAX_PATH );` – BurninatorDor Sep 05 '14 at 18:36
- 
                    1@BurninatorDor Don't call yourself a newbie. I've been programming in MFC for 6 years thus far, and this helped me. – Neil Sep 11 '14 at 09:33
- 
                    2edited this answer because it was calculating the version numbers wrong. From the MSDN docs for dwProductVersionMS: "The most significant 32 bits of the file's binary version number. This member is used with dwFileVersionLS to form a 64-bit value used for numeric comparisons." , so you use both of them to calculate the version number. First two (major / minor) are in versionMS and last two (revision / build) are in versionLS. It doesn't matter if you are in 32/64 bit, DWORD is always 32 bits. – mgrandi Nov 12 '14 at 00:28
- 
                    Make sure to link to libversion.a for MingW. See here for copy-pastable example: http://pastebin.com/sYZCVpfw – Aralox Sep 26 '15 at 02:50
- 
                    1
- 
                    Have to add version.lib to additional linker dependences. Referencing Mincore.lib as official docs suggest didn't work for me. – Aleksandr May 04 '18 at 05:48
- 
                    How to get file version for MSI files, GetFileVersionInfoSize giving error 1812 – user3664223 Feb 18 '22 at 06:50
- 
                    @user3664223 It is possible that a MSI file may not have that information block. – crashmstr Feb 18 '22 at 15:30
All these solutions did not work properly (with my system). I found out that each of the four parts of the version number are saved as a 16-bit value.
The first two numbers are saved in the 32-bit DWORD dwFileVersionMS, and the second two in dwFileVersionLS. So I edited your code at the output section like this:
    TRACE( "File Version: %d.%d.%d.%d\n",
        ( pFileInfo->dwFileVersionMS >> 16 ) & 0xffff,
        ( pFileInfo->dwFileVersionMS >>  0 ) & 0xffff,
        ( pFileInfo->dwFileVersionLS >> 16 ) & 0xffff,
        ( pFileInfo->dwFileVersionLS >>  0 ) & 0xffff
        );
And it works perfectly. The output is formatted like on my system:
major.minor.build.revision
 
    
    - 30,738
- 21
- 105
- 131
 
    
    - 651
- 6
- 17
- 
                    How to get file version for MSI files, GetFileVersionInfoSize giving error 1812? – user3664223 Feb 18 '22 at 06:50
You get this information using the version information APIs. Here is a sample:
void PrintFileVersion( TCHAR *pszFilePath )
{
    DWORD               dwSize              = 0;
    BYTE                *pbVersionInfo      = NULL;
    VS_FIXEDFILEINFO    *pFileInfo          = NULL;
    UINT                puLenFileInfo       = 0;
    // Get the version information for the file requested
    dwSize = GetFileVersionInfoSize( pszFilePath, NULL );
    if ( dwSize == 0 )
    {
        printf( "Error in GetFileVersionInfoSize: %d\n", GetLastError() );
        return;
    }
    pbVersionInfo = new BYTE[ dwSize ];
    if ( !GetFileVersionInfo( pszFilePath, 0, dwSize, pbVersionInfo ) )
    {
        printf( "Error in GetFileVersionInfo: %d\n", GetLastError() );
        delete[] pbVersionInfo;
        return;
    }
    if ( !VerQueryValue( pbVersionInfo, TEXT("\\"), (LPVOID*) &pFileInfo, &puLenFileInfo ) )
    {
        printf( "Error in VerQueryValue: %d\n", GetLastError() );
        delete[] pbVersionInfo;
        return;
    }
    // pFileInfo->dwFileVersionMS is usually zero. However, you should check
    // this if your version numbers seem to be wrong
    printf( "File Version: %d.%d.%d.%d\n",
        ( pFileInfo->dwFileVersionLS >> 24 ) & 0xff,
        ( pFileInfo->dwFileVersionLS >> 16 ) & 0xff,
        ( pFileInfo->dwFileVersionLS >>  8 ) & 0xff,
        ( pFileInfo->dwFileVersionLS >>  0 ) & 0xff
        );
    // pFileInfo->dwProductVersionMS is usually zero. However, you should check
    // this if your version numbers seem to be wrong.
    printf( "Product Version: %d.%d.%d.%d\n",
        ( pFileInfo->dwProductVersionLS >> 24 ) & 0xff,
        ( pFileInfo->dwProductVersionLS >> 16 ) & 0xff,
        ( pFileInfo->dwProductVersionLS >>  8 ) & 0xff,
        ( pFileInfo->dwProductVersionLS >>  0 ) & 0xff
        );
}
 
    
    - 30,738
- 21
- 105
- 131
 
    
    - 40,684
- 18
- 101
- 169
- 
                    3I think this is wrong. for file version 1.0.0.1 this function gives me "0.0.0.1". I ended up @Vasya 's answer – liorda Mar 18 '13 at 10:20
- 
                    There is a memory leak. `pbVersionInfo` is not released at the end of the function. – Dmytro Ovdiienko May 12 '22 at 09:04
Found these articles...sorry, but I don't have direct experience with how to do this using native APIs, so I deferred to an Internet search:
- C++: Determining the version number of a DLL or Executable
- VB (probably version 6): How to Use Functions in VERSION.DLL
Hope these help!
 
    
    - 667
- 6
- 10
This code shows the file version numbers correctly.
( pFileInfo->dwFileVersionMS >> 16 ) & 0xff,
( pFileInfo->dwFileVersionMS >> 0 ) & 0xff,
( pFileInfo->dwFileVersionLS >>  16 ) & 0xff,
( pFileInfo->dwFileVersionLS >>  0 ) & 0xff);
- 
                    4Can you provide some context to this answer? It seems to be incomplete. If it was a correction to another answer, please leave a comment on it, or edit that answer and it will be approved by a more experianced user. – Deanna Oct 16 '12 at 08:00
- 
                    1this will definitely _not_ work correctly, if the version includes any component greater than 255, e.g. 6.1.3709.2 The four components are 16-bit numbers, not 8-bit. – Spike0xff Nov 23 '16 at 02:39
- 
                    This is not correct. The individual parts of the versions are 16-bit values. The code should be ( pFileInfo->dwFileVersionMS >> 16 ) & 0xffff, ( pFileInfo->dwFileVersionMS >> 0 ) & 0xffff, ( pFileInfo->dwFileVersionLS >> 16 ) & 0xffff, ( pFileInfo->dwFileVersionLS >> 0 ) & 0xffff); – DaveCleland Apr 11 '20 at 16:56
- 
                    As it was a long time ago !!! But I can share the solution. I then refused to receive information about executable files from the kernel driver. I then transferred this function to the service. The driver transmitted information about the start of the process and expected a resolution from the service – Vasya Apr 12 '20 at 19:44
The easiest way is to use the GetFileVersionInfoEx or GetFileVersionInfo API functions.
You can also do it from within your application resources as explained here.
 
    
    - 6,169
- 3
- 26
- 45
 
     
    