CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 1 of 1
  1. #1
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652

    Windows SDK Application: How to retrieve the version information of my application?

    Q: How to retrieve the version information of my application?

    A: To retrieve the version information you can use the following functions...
    Code:
    DWORD GetFileVersionInfoSize(LPTSTR lptstrFilename, LPDWORD lpdwHandle)
    
    BOOL GetFileVersionInfo(LPTSTR lptstrFilename,
                            DWORD  dwHandle,
                            DWORD  dwLen,
                            LPVOID lpData)
    
    BOOL VerQueryValue(const LPVOID pBlock,
                       LPTSTR       lpSubBlock,
                       LPVOID       *lplpBuffer,
                       PUINT        puLen)
    
    DWORD VerLanguageName(DWORD wLang, LPTSTR szLang, DWORD nSize)
    'GetFileVersionInfoSize()' returns the size of the version information. 'GetFileVersionInfo()' uses information retrieved by 'GetFileVersionInfoSize()' to retrieve a structure that contains the version information. 'VerQueryValue()' retrieves a specific member from that structure. Your setup program needs to call those function depending on the error code returned by e.g. 'VerInstallFile()'.

    The following is an example class which wraps the whole thing...
    Code:
    // version.hpp
    
    #ifndef VERSION
    #define VERSION
    
    #pragma warning(disable : 4505 4710)
    #pragma comment(lib, "version.lib")
    
    #include <string>
    #include <sstream>
    #include <iomanip>
    #include <exception>
    #include <new>
    #include <windows.h>
    
    
    namespace version_nmsp
    {
      struct language
      {
        WORD language_;
        WORD code_page_;
    
        language()
        {
          language_  = 0;
          code_page_ = 0;
        }
      };
    }
    
    
    class version
    {
    public:
      version()
      {
        // Get application name
        TCHAR buf[MAX_PATH] = "";
    
        if(::GetModuleFileName(0, buf, sizeof(buf)))
        {
          std::string app_name = buf;
          app_name             = app_name.substr(app_name.rfind("\\") + 1);
    
          // Get version info
          DWORD h = 0;
    
          DWORD resource_size = ::GetFileVersionInfoSize(const_cast<char*>(app_name.c_str()), &h);
          if(resource_size)
          {
            resource_data_ = new unsigned char[resource_size];
            if(resource_data_)
            {
              if(::GetFileVersionInfo(const_cast<char*>(app_name.c_str()),
                                      0,
                                      resource_size,
                                      static_cast<LPVOID>(resource_data_)) != FALSE)
              {
                UINT size = 0;
    
                // Get language information
                if(::VerQueryValue(static_cast<LPVOID>(resource_data_),
                                   "\\VarFileInfo\\Translation",
                                   reinterpret_cast<LPVOID*>(&language_information_),
                                   &size) == FALSE)
                  throw std::exception("Requested localized version information not available");
              }
              else
              {
                std::stringstream exception;
                exception << "Could not get version information (Windows error: " << ::GetLastError() << ")";
                throw std::exception(exception.str().c_str());
              }
            }
            else
              throw std::bad_alloc();
          }
          else
          {
            std::stringstream exception;
            exception << "No version information found (Windows error: " << ::GetLastError() << ")";
            throw std::exception(exception.str().c_str());
          }
        }
        else
          throw std::exception("Could not get application name");
      }
    
      ~version() { delete [] resource_data_; }
      std::string get_product_name() const { return get_value("ProductName"); }
      std::string get_internal_name() const { return get_value("InternalName"); }
      std::string get_product_version() const { return get_value("ProductVersion"); }
      std::string get_special_build() const { return get_value("SpecialBuild"); }
      std::string get_private_build() const { return get_value("PrivateBuild"); }
      std::string get_copyright() const { return get_value("LegalCopyright"); }
      std::string get_trademarks() const { return get_value("LegalTrademarks"); }
      std::string get_comments() const { return get_value("Comments"); }
      std::string get_company_name() const { return get_value("CompanyName"); }
      std::string get_file_version() const { return get_value("FileVersion"); }
      std::string get_file_description() const { return get_value("FileDescription"); }
    
    private:
      unsigned char          *resource_data_;
      version_nmsp::language *language_information_;
    
      std::string get_value(const std::string &key) const
      {
        if(resource_data_)
        {
          UINT              size   = 0;
          std::stringstream t;
          LPVOID            value  = 0;
    
          // Build query string
          t << "\\StringFileInfo\\" << std::setw(4) << std::setfill('0') << std::hex
            << language_information_->language_ << std::setw(4) << std::hex
            << language_information_->code_page_ << "\\" << key;
    
          if(::VerQueryValue(static_cast<LPVOID>(resource_data_),
                             const_cast<LPTSTR>(t.str().c_str()),
                             static_cast<LPVOID*>(&value),
                             &size) != FALSE)
            return static_cast<LPTSTR>(value);
        }
    
        return "";
      }
    };
    
    #endif
    The above class can be used as follows:
    Code:
    #include <iostream>
    #include <version.hpp>
    #include <conio.h>
    
    int main()
    {
      try
      {
        version v;
        std::cout << v.get_product_name() << std::endl;
      }
      catch(const std::exception& e)
      {
        std::cerr << e.what() << std::endl;
      }
    
      _getch();
    
      return 0;
    }
    Last edited by Andreas Masur; January 31st, 2006 at 05:04 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured