views:

938

answers:

6

I need to get the product version and file version for a dll or exe 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, selecting "Properties", then looking at the "Details" tab. This is usually a four-part dotted version number x.x.x.x.

A: 

Those sorts of things are often stored in the registry.

Shane C. Mason
+4  A: 

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:

Hope these help!

Steve J
+8  A: 

GetFileVersionInfo()

Matt Schmidt
+11  A: 
crashmstr
In practice I've found that the build is the HIWORD, and the LOWORD is the number after the last dot, which is almost always 0. Otherwise, this is correct.
JSBangs
I generally only worry about 3 numbers for my apps, so I just grab the value. Which ends up being like A.B.0.C But if you wanted all four, then you would need to HIWORD/LOWORD the other.
crashmstr
+3  A: 

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.

Dani van der Meer
+6  A: 

[Self-answering, since it took me a lot of Googling to get the right answer to this question, and right now the top Google hits are misleading.]

You get this information using the Version Information APIs (http://msdn.microsoft.com/en-us/library/ms646981.aspx). Here is a sample:

void PrintFileVersion( TCHAR *pszFilePath )
{
    DWORD               dwSize              = 0;
    BYTE                *pbVersionInfo      = NULL;
    VS_FIXEDFILEINFO    *pFileInfo          = NULL;
    UINT                puLenFileInfo       = 0;

    // get the version info 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
        );

}
JSBangs
+1 since this code this code is better (new and delete), however what worked for me for the printf was this: `printf( "File Version: %d.%d.%d.%d\n", ` `HIWORD(pFileInfo->dwFileVersionMS ), ` `LOWORD(pFileInfo->dwFileVersionMS ), ` `HIWORD( pFileInfo->dwFileVersionLS ), ` `LOWORD( pFileInfo->dwFileVersionLS ) ); `
CharlesB