Click here to Skip to main content
15,352,679 members
Articles / Programming Languages / C++
Posted 22 Oct 2004


57 bookmarked

Retrieving version information from your local application's resource

Rate me:
Please Sign up or sign in to vote.
4.55/5 (25 votes)
22 Oct 20042 min read
Sample code to retrieve version information from your local application

Sample Image - Version.gif


This application contains a small class supporting access to the version information stored in YOUR OWN Win32 application.


There is a lot code around the Internet, showing how easy it is to retrieve version information from any EXE or DLL. I never really liked the idea, opening my own application's file again (using GetFileVersionInfo()) simply to be able to access my local version data.

It took me quite some searching and other people's free source code to understand how this information may be retrieved from the local application's resource (equivalent to CString::LoadString() etc.).

Using the code

First of all: Be happy to use this code to your convenience and modify/enhance it as you like.

This is what you have to do 1. Add version.lib to your project's libraries 2. Add "#include <winver.h>" to your stdafx.h (could also be included to CGlobalFunctions.cpp instead) 3. Add GlobalFunctions.h and CGlobalFunctions.cpp to your project 4. Call any of the static functions from anywhere in your application


class CGlobalFunctions  : public CObject
    virtual ~CGlobalFunctions();
    static CString GetFileVersionX();
    static CString GetProductVersionX();
    static CString GetVersionInfo(HMODULE hLib, CString csEntry);
    static CString FormatVersion(CString cs);

    static CString m_csFileVersion;
    static CString m_csProductVersion;

GlobalFunctions.cpp: (see source code for more detailed description of the methods)

String CGlobalFunctions::m_csFileVersion;
CString CGlobalFunctions::m_csProductVersion;




// This is the key method
CString CGlobalFunctions::GetVersionInfo(HMODULE hLib, CString csEntry)
  CString csRet;

  if (hLib == NULL)
    hLib = AfxGetResourceHandle();
  HRSRC hVersion = FindResource( hLib, 
  if (hVersion != NULL)
    HGLOBAL hGlobal = LoadResource( hLib, hVersion ); 
    if ( hGlobal != NULL)  
      LPVOID versionInfo  = LockResource(hGlobal);  
      if (versionInfo != NULL)
        DWORD vLen,langD;
        BOOL retVal;    
        LPVOID retbuf=NULL;
        static char fileEntry[256];

        retVal = VerQueryValue(versionInfo,fileEntry,&retbuf,(UINT *)&vLen);
        if (retVal && vLen==4) 
          sprintf(fileEntry, "\\StringFileInfo\\%02X%02X%02X%02X\\%s",
                  (langD & 0xff00)>>8,langD & 0xff,(langD & 0xff000000)>>24, 
                  (langD & 0xff0000)>>16, csEntry);            
          sprintf(fileEntry, "\\StringFileInfo\\%04X04B0\\%s", 
            GetUserDefaultLangID(), csEntry);

        if (VerQueryValue(versionInfo,fileEntry,&retbuf,(UINT *)&vLen)) 
          csRet = (char*)retbuf;

    UnlockResource( hGlobal );  
    FreeResource( hGlobal );  

  return csRet;

// Re-formats a string formatted as "m,n,o,p" to format as "m.nop"
CString CGlobalFunctions::FormatVersion(CString cs)
  CString csRet;
  if (!cs.IsEmpty())
    int iPos = cs.Find(',');
    if (iPos == -1)
      return "";
    csRet.Format("%s.", cs.Left(iPos));

    while (1)
      cs = cs.Mid(iPos + 1);
      iPos = cs.Find(',');
      if (iPos == -1)
        csRet +=cs;
      csRet += cs.Left(iPos);

  return csRet;

// Loads "FileVersion" from resource formats it and keeps it in mind
CString CGlobalFunctions::GetFileVersionX()
  if (m_csFileVersion.IsEmpty())
    CString csVersion = FormatVersion(GetVersionInfo(NULL, "FileVersion"));
    m_csFileVersion.Format("Version %s (Build %s)", 
      csVersion, GetVersionInfo(NULL, "SpecialBuild"));

  return m_csFileVersion;

// Loads "ProductVersion" from resource formats it and keeps it in mind
CString CGlobalFunctions::GetProductVersionX()
  if (m_csProductVersion.IsEmpty())
    m_csProductVersion = FormatVersion(GetVersionInfo(NULL, "ProductVersion"));

  return m_csProductVersion;

Using it anywhere in the application: (e.g. in CGetVersionApp::InitInstance())

  CString cs;
  cs.Format("FileVersion: %s\nProductVersion: %s\nMyPrivateInfo: %s", 
             CGlobalFunctions::GetVersionInfo(NULL, "MyPrivateInfo"));

Points of Interest

Well, if you take a close look (while debuging) at fileEntry your will notify it's containig "\StringFileInfo\040704B0\ProductVersion". Compare this path with the structure of Version in the *.rc-file. This makes clear how the access of the version information works:


    BLOCK "StringFileInfo"
        BLOCK "040704b0"
            VALUE "Comments", "\0"
            VALUE "CompanyName", "\0"
            VALUE "FileDescription", "MFC-Anwendung GetVersion\0"
            VALUE "FileVersion", "1, 2, 3, a\0"
            VALUE "InternalName", "GetVersion\0"
            VALUE "LegalCopyright", "Copyright (C) 2004\0"
            VALUE "LegalTrademarks", "\0"
            VALUE "OriginalFilename", "GetVersion.EXE\0"
            VALUE "PrivateBuild", "\0"
            VALUE "ProductName", "Anwendung GetVersion\0"
            VALUE "ProductVersion", "1, 0, 0, a\0"
            VALUE "SpecialBuild", "2\0"
            VALUE "MyPrivateInfo", 
              "This is an privately defined version information\0"
    BLOCK "VarFileInfo"
        VALUE "Translation", 0x407, 1200

NOTE: I have extended the version information structure by an own entry ("MyPrivateInfo"). You may retrieve this information in the same way as you can using all the predefined entries.

List of predefined entries within the version information structure: Comments CompanyName FileDescription FileVersion InternalName LegalCopyright LegalTrademarks OriginalFilename PrivateBuild ProductName ProductVersion SpecialBuild

Further recommendation

As you know from Microsoft products, beside the version information they specify a build code e.g. (Build 1376). There is a free add-in for Visual C++ that automatically increments the "SpecialBuild" entry within your *.rc file. It has been developed by Mihai Filimon and is called IncPrivateBuild. Click here for more information. It comes with the source code an is a really cool tool.

Cheers and enjoy this code, Hartmut


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Switzerland Switzerland
No Biography provided

Comments and Discussions

AnswerGPF is due to resource locking Pin
USchmitt27-Mar-13 20:50
MemberUSchmitt27-Mar-13 20:50 
QuestionAnother codes to get file version. Pin
cigarhuang20-Aug-12 3:15
Membercigarhuang20-Aug-12 3:15 
AnswerRe: Another codes to get file version. Pin
Andrew Phillips29-Aug-12 14:52
MemberAndrew Phillips29-Aug-12 14:52 
You are missing the point, like many posters here. It is well known how to get version info from a file (EXE or DLL containing version resource) using GetFileVersionInfoSize, GetFileVersionInfo, VerQueryValue, etc.

The whole point of the articel was to get the version resource directly, without going back to the disk file, in the same way you can get string resources and other resources.
Andrew Phillips
andrew @

Bugthis code crashes, use one from msdn instead Pin
Dmitriy Bryndin12-Apr-12 14:12
MemberDmitriy Bryndin12-Apr-12 14:12 
GeneralRe: this code crashes, use one from msdn instead Pin
Member 861328811-May-12 1:10
MemberMember 861328811-May-12 1:10 
BugVerQueryInfo writes to the pointer Pin
kjhsdfksdhfjkds11-Dec-11 8:43
Memberkjhsdfksdhfjkds11-Dec-11 8:43 
GeneralCode doesn't compile for Unicode apps. Pin
Arfa24-Nov-10 3:43
MemberArfa24-Nov-10 3:43 
News.NET Version for the same Pin
dB.30-Jun-08 8:55
MemberdB.30-Jun-08 8:55 
GeneralWrong method to get the version info that generates Access violation Pin
alegall66613-Mar-08 3:33
Memberalegall66613-Mar-08 3:33 
GeneralThanks a lot Pin
723Alex22-May-07 7:19
Member723Alex22-May-07 7:19 
GeneralAccess Violation:: Pin
zwu_ca15-May-07 14:12
Memberzwu_ca15-May-07 14:12 
GeneralRe: Access Violation:: Pin
luetz15-May-07 20:53
Memberluetz15-May-07 20:53 
GeneralRe: Access Violation:: Pin
KaniSDragon19-Oct-07 19:45
MemberKaniSDragon19-Oct-07 19:45 
GeneralThanks! Pin
Nguyễn Thiện Nhẫn2-May-07 18:09
MemberNguyễn Thiện Nhẫn2-May-07 18:09 
GeneralRe: Thanks! Pin
luetz15-May-07 21:03
Memberluetz15-May-07 21:03 
GeneralVerQueryValue fails Pin
rumblef23-Jun-05 5:29
Memberrumblef23-Jun-05 5:29 
GeneralAdd the logic of removing trailing zeros from version in FormatVersion Pin
sonawane ajay7-Mar-05 20:39
Membersonawane ajay7-Mar-05 20:39 
GeneralRe: Add the logic of removing trailing zeros from version in FormatVersion Pin
t0671dl20-Jun-05 5:43
Membert0671dl20-Jun-05 5:43 
GeneralRe: Add the logic of removing trailing zeros from version in FormatVersion Pin
sonawane ajay20-Jun-05 18:37
Membersonawane ajay20-Jun-05 18:37 
GeneralWow! Pin
309DA944-69E5-4f18-9E33-56D805BE5BD113-Jan-05 9:05
suss309DA944-69E5-4f18-9E33-56D805BE5BD113-Jan-05 9:05 
GeneralMemory Fault Pin
coferm28-Oct-04 5:39
Membercoferm28-Oct-04 5:39 
GeneralRe: Memory Fault Pin
fazorin2-Nov-04 0:27
Memberfazorin2-Nov-04 0:27 
GeneralNice Pin
Jiju George T27-Oct-04 15:01
MemberJiju George T27-Oct-04 15:01 
GeneralThanks for the code! Pin
Rolando Cruz26-Oct-04 2:40
MemberRolando Cruz26-Oct-04 2:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.