Version Info in runtime Topic is solved

If you are using wxDev-C++ for your wxWidgets design, please ask your questions here instead of in IDE Related.
Post Reply
Tobi
Earned a small fee
Earned a small fee
Posts: 10
Joined: Mon May 15, 2006 6:08 am

Version Info in runtime

Post by Tobi »

In Menu "Project Options"->"Version Info" you are able to specify a version of your program.
Is it possible to show this version to the user in runtime of my program? (Maybe in a wxStaticText field?)
upCASE
Moderator
Moderator
Posts: 3176
Joined: Mon Aug 30, 2004 6:55 am
Location: Germany, Cologne

Re: Version Info in runtime

Post by upCASE »

Tobi wrote:In Menu "Project Options"->"Version Info" you are able to specify a version of your program.
Is it possible to show this version to the user in runtime of my program? (Maybe in a wxStaticText field?)
Yes, although not by using wxWidgets. This is a platform issue as the version info is placed in the resources of your app. Only on Windows you can use these.
Have a look here for a nice class that can help you to get the info:
http://www.codeguru.com/cpp/misc/misc/v ... .php/c319/
It's MFC but should be easily portable. If you have problems with that, say so and I'll see what I can do and place it in the code dump.
OS: OpenSuSE, Ubuntu, Win XP Pro
wx: svn
Compiler: gcc 4.5.1, VC 2008, eVC 4

"If it was hard to write it should be hard to read..." - the unknown coder
"Try not! Do. Or do not. There is no try." - Yoda
Tobi
Earned a small fee
Earned a small fee
Posts: 10
Joined: Mon May 15, 2006 6:08 am

Post by Tobi »

Looks nice, but I DO HAVE PROBLEMS with that.
My compiler can not find the stdafx.h. I had to download it, but I am not sure if it fits into wxDevCPP?
Then I must change all the CString into wxString, right?
Then it will not find the ASSERT function. Do I have to replace this with a wxDevCPP function? Which one, what should this function do?

And then how to call it?
I tried something like

Code: Select all

    FileVersion *FCCM = new FileVersion;
    WxEdit1->SetValue(FCCM.GetFileVersion());
I think I have to open the module first. But what is the module? If it is the complete filename, how to get it? (User can change it...)

So many problems, sorry...
HeReSY
Earned some good credits
Earned some good credits
Posts: 120
Joined: Fri Sep 17, 2004 8:58 pm
Location: Germany

Post by HeReSY »

there is a header file which contains the informations about the version.
<projectname>_private.h
include it to your project and compile it, then you can use the version information.

HeReSY
upCASE
Moderator
Moderator
Posts: 3176
Joined: Mon Aug 30, 2004 6:55 am
Location: Germany, Cologne

Post by upCASE »

Tobi wrote:My compiler can not find the stdafx.h. I had to download it, but I am not sure if it fits into wxDevCPP?
Nope, it doesn't. VC/MFC only stuff you don't need and want :)
Tobi wrote:Then I must change all the CString into wxString, right?
In a way, yes. You'd have to change some other things too.
Tobi wrote:Then it will not find the ASSERT function. Do I have to replace this with a wxDevCPP function? Which one, what should this function do?
wxASSERT is the way to go :)
Tobi wrote:I think I have to open the module first. But what is the module? If it is the complete filename, how to get it? (User can change it...)

Code: Select all

char szExeName[MAX_PATH];
GetModuleFileName(NULL, szExeName, sizeof (szExeName));
This would give you the name of the current running module.

Anyway, I created a small converted version called wxFileVersion.
I tested it with VC and it works. I suppose it should work with gcc, too. Note that when compiling you'll need to add version.lib ( libversion.a, or -lversion for gcc) in the linker list.

wxFileVersion.h

Code: Select all

#ifndef __FILEVERSION_H_
#define __FILEVERSION_H_

#include <wx/wx.h>

#ifdef __WXMSW__

class wxFileVersion
{

public:
    wxFileVersion();


public:
    bool    Open(wxString strModuleName=wxEmptyString);
    void    Close();

    wxString QueryValue(wxString strValueName, unsigned long dwLangCharset = 0);

    wxString GetFileDescription()  {return QueryValue(wxT("FileDescription")); };
    wxString GetFileVersion()      {return QueryValue(wxT("FileVersion"));     };
    wxString GetInternalName()     {return QueryValue(wxT("InternalName"));    };
    wxString GetCompanyName()      {return QueryValue(wxT("CompanyName"));     };
    wxString GetLegalCopyright()   {return QueryValue(wxT("LegalCopyright"));  };
    wxString GetOriginalFilename() {return QueryValue(wxT("OriginalFilename"));};
    wxString GetProductName()      {return QueryValue(wxT("ProductName"));     };
    wxString GetProductVersion()   {return QueryValue(wxT("ProductVersion"));  };

    bool    GetFixedInfo(VS_FIXEDFILEINFO& vsffi);
    wxString GetFixedFileVersion();
    wxString GetFixedProductVersion();

protected:
    unsigned char*  m_lpVersionData;
    unsigned long   m_dwLangCharset;

public:
    ~wxFileVersion();
};

#endif //__WXMSW__
#endif  // __FILEVERSION_H_
wxFileVersion.cpp

Code: Select all

#include "wxFileVersion.h"

#ifdef __WXMSW__
/
wxFileVersion::wxFileVersion()
{
    m_lpVersionData = NULL;
    m_dwLangCharset = 0;
}

wxFileVersion::~wxFileVersion()
{
    Close();
}

void wxFileVersion::Close()
{
    delete[] m_lpVersionData;
    m_lpVersionData = NULL;
    m_dwLangCharset = 0;
}

bool wxFileVersion::Open(wxString strModuleName)
{
    if(strModuleName.IsEmpty())
	{
		char szExeName[MAX_PATH];
		GetModuleFileName(NULL, szExeName, sizeof (szExeName));
		strModuleName = szExeName;
	}

	wxASSERT(!strModuleName.IsEmpty());
    wxASSERT(m_lpVersionData == NULL);

    unsigned long dwHandle;
    unsigned long dwDataSize = ::GetFileVersionInfoSize(strModuleName.mb_str(wxConvUTF8), &dwHandle);
    if ( dwDataSize == 0 )
        return false;


    m_lpVersionData = new unsigned char[dwDataSize];
    if (!::GetFileVersionInfo(strModuleName.mb_str(wxConvUTF8), dwHandle, dwDataSize,
	                          (void**)m_lpVersionData) )
    {
        Close();
        return false;
    }

    unsigned int nQuerySize;
    unsigned long* pTransTable;
    if (!::VerQueryValue(m_lpVersionData, wxT("\\VarFileInfo\\Translation"),
                         (void **)&pTransTable, &nQuerySize) )
    {
        Close();
        return false;
    }

    m_dwLangCharset = MAKELONG(HIWORD(pTransTable[0]), LOWORD(pTransTable[0]));

    return true;
}

wxString wxFileVersion::QueryValue(wxString strValueName,
                                 unsigned long dwLangCharset /* = 0*/)
{
 
    wxASSERT(m_lpVersionData != NULL);
    if ( m_lpVersionData == NULL )
        return wxEmptyString;

    if ( dwLangCharset == 0 )
        dwLangCharset = m_dwLangCharset;

    unsigned int nQuerySize;
    void* lpData;
    wxString strValue, strBlockName;
	strBlockName = wxString::Format(wxT("\\StringFileInfo\\%08lx\\%s"),
	                     dwLangCharset, strValueName);

    if ( ::VerQueryValue((void **)m_lpVersionData, (char*)strBlockName.mb_str(wxConvUTF8),
	                     &lpData, &nQuerySize) )
		strValue = wxString::FromAscii((char*)lpData);

    return strValue;
}

bool wxFileVersion::GetFixedInfo(VS_FIXEDFILEINFO& vsffi)
{
    wxASSERT(m_lpVersionData != NULL);
    if ( m_lpVersionData == NULL )
        return false;

    unsigned int nQuerySize;
	VS_FIXEDFILEINFO* pVsffi;
    if ( ::VerQueryValue((void **)m_lpVersionData, wxT("\"),
                         (void**)&pVsffi, &nQuerySize) )
    {
        vsffi = *pVsffi;
        return true;
    }

    return false;
}

wxString wxFileVersion::GetFixedFileVersion()
{
    wxString strVersion;
	VS_FIXEDFILEINFO vsffi;

    if ( GetFixedInfo(vsffi) )
    {
		strVersion = wxString::Format ("%u,%u,%u,%u",HIWORD(vsffi.dwFileVersionMS),
            LOWORD(vsffi.dwFileVersionMS),
            HIWORD(vsffi.dwFileVersionLS),
            LOWORD(vsffi.dwFileVersionLS));
    }
    return strVersion;
}

wxString wxFileVersion::GetFixedProductVersion()
{
    wxString strVersion;
	VS_FIXEDFILEINFO vsffi;

    if ( GetFixedInfo(vsffi) )
    {
		strVersion = wxString::Format ("%u,%u,%u,%u", HIWORD(vsffi.dwProductVersionMS),
            LOWORD(vsffi.dwProductVersionMS),
            HIWORD(vsffi.dwProductVersionLS),
            LOWORD(vsffi.dwProductVersionLS));
    }
    return strVersion;
}
#endif //__WXMSW__
Hope this helps a little. :)
OS: OpenSuSE, Ubuntu, Win XP Pro
wx: svn
Compiler: gcc 4.5.1, VC 2008, eVC 4

"If it was hard to write it should be hard to read..." - the unknown coder
"Try not! Do. Or do not. There is no try." - Yoda
Tobi
Earned a small fee
Earned a small fee
Posts: 10
Joined: Mon May 15, 2006 6:08 am

Post by Tobi »

Hi HeReSY,

thats a very simple and working solution. So much thanks to you. This forum is great!

THANKS!!!!!
Tobi
Earned a small fee
Earned a small fee
Posts: 10
Joined: Mon May 15, 2006 6:08 am

Post by Tobi »

And of course a big thanks to upCASE, who helps with his very descriptive answers to understand the background much better. Sorry you had so much work, although there was an easy way. THANKS.
Widgets
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 534
Joined: Thu Jun 01, 2006 4:36 pm
Location: Right here!

Re: Version Info in runtime

Post by Widgets »

Found this code very helpful, but had to adapt it a bit for wxWidgets 3.0.2 & Unicode

wxFileVersion.h stays the same.
my wxFileVersion.cpp

Code: Select all

#ifdef __WXMSW__

wxFileVersion::wxFileVersion()
{
  m_lpVersionData = NULL;
  m_dwLangCharset = 0;
}

wxFileVersion::~wxFileVersion()
{
  Close();
}

void wxFileVersion::Close()
{
  delete[] m_lpVersionData;
  m_lpVersionData = NULL;
  m_dwLangCharset = 0;
}

bool wxFileVersion::Open(wxString strModuleName)
{
  if(strModuleName.IsEmpty())
  {
    wchar_t szExeName[MAX_PATH];
    GetModuleFileName(NULL, szExeName, sizeof (szExeName));
    strModuleName = szExeName;
  }

  wxASSERT(!strModuleName.IsEmpty());
  wxASSERT(m_lpVersionData == NULL);

  unsigned long dwHandle;
  unsigned long dwDataSize = ::GetFileVersionInfoSize(strModuleName.wc_str(wxConvUTF8), &dwHandle);
  if ( dwDataSize == 0 )
      return false;


  m_lpVersionData = new unsigned char[dwDataSize];
  if (!::GetFileVersionInfo(strModuleName.wc_str(wxConvUTF8), dwHandle, dwDataSize,
                            (void**)m_lpVersionData) )
  {
      Close();
      return false;
  }

  unsigned int nQuerySize;
  unsigned long* pTransTable;
  if (!::VerQueryValue(m_lpVersionData, wxT("\\VarFileInfo\\Translation"),
                        (void **)&pTransTable, &nQuerySize) )
  {
      Close();
      return false;
  }

  m_dwLangCharset = MAKELONG(HIWORD(pTransTable[0]), LOWORD(pTransTable[0]));

  return true;
}

wxString wxFileVersion::QueryValue(wxString strValueName,
                                 unsigned long dwLangCharset /* = 0*/)
{
 
  wxASSERT(m_lpVersionData != NULL);
  if ( m_lpVersionData == NULL )
      return wxEmptyString;

  if ( dwLangCharset == 0 )
      dwLangCharset = m_dwLangCharset;

  unsigned int nQuerySize;
  void* lpData;
  wxString strValue, strBlockName;
  strBlockName = wxString::Format(wxT("\\StringFileInfo\\%08lx\\%s"),
                      dwLangCharset, strValueName);

  if ( ::VerQueryValue((void **)m_lpVersionData, strBlockName.wc_str(wxConvUTF8),
                      &lpData, &nQuerySize) )
//    strValue = wxString::FromAscii((char*)lpData);
    strValue = (wxStringCharType *)((char*)lpData );

  return strValue;
}

bool wxFileVersion::GetFixedInfo(VS_FIXEDFILEINFO& vsffi)
{
  wxASSERT(m_lpVersionData != NULL);
  if ( m_lpVersionData == NULL )
      return false;

  unsigned int nQuerySize;
  VS_FIXEDFILEINFO* pVsffi;
  if ( ::VerQueryValue((void **)m_lpVersionData, wxT("\\"),
                        (void**)&pVsffi, &nQuerySize) )
  {
      vsffi = *pVsffi;
      return true;
  }

  return false;
}

wxString wxFileVersion::GetFixedFileVersion()
{
  wxString strVersion;
  VS_FIXEDFILEINFO vsffi;

  if ( GetFixedInfo(vsffi) )
  {
    strVersion = wxString::Format ("%u,%u,%u,%u",HIWORD(vsffi.dwFileVersionMS),
          LOWORD(vsffi.dwFileVersionMS),
          HIWORD(vsffi.dwFileVersionLS),
          LOWORD(vsffi.dwFileVersionLS));
  }
  return strVersion;
}

wxString wxFileVersion::GetFixedProductVersion()
{
  wxString strVersion;
  VS_FIXEDFILEINFO vsffi;

  if ( GetFixedInfo(vsffi) )
  {
    strVersion = wxString::Format ("%u,%u,%u,%u", HIWORD(vsffi.dwProductVersionMS),
          LOWORD(vsffi.dwProductVersionMS),
          HIWORD(vsffi.dwProductVersionLS),
          LOWORD(vsffi.dwProductVersionLS));
  }
  return strVersion;
}
#endif //__WXMSW__
Environment: Win 10/11 64-bit & Mint 21.1
MSVC Express 2019/2022
wxWidgets 3.2.2
Gnawer
Experienced Solver
Experienced Solver
Posts: 65
Joined: Thu Jun 29, 2006 11:10 am
Location: Ahlen, Germany

Re: Version Info in runtime

Post by Gnawer »

Great, that you post this piece of code that helps to retrieve all the version information! =D>
It maybe mentioned additionally, that you have to link with "version.lib".
Best regards
Gnawer
Post Reply