Page 1 of 1

Version Info in runtime

Posted: Wed May 17, 2006 2:10 am
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?)

Re: Version Info in runtime

Posted: Wed May 17, 2006 7:19 am
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.

Posted: Wed May 17, 2006 8:53 am
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...

Posted: Wed May 17, 2006 10:41 am
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

Posted: Wed May 17, 2006 10:58 am
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. :)

Posted: Thu May 18, 2006 9:36 am
by Tobi
Hi HeReSY,

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

THANKS!!!!!

Posted: Thu May 18, 2006 9:39 am
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.

Re: Version Info in runtime

Posted: Fri Apr 22, 2016 11:25 pm
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__

Re: Version Info in runtime

Posted: Mon Sep 16, 2019 9:54 am
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".