Version Info in runtime  [SOLVED]

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

Version Info in runtime

Postby Tobi » Wed May 17, 2006 2:10 am

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
Site Admin
Site Admin
Posts: 3176
Joined: Mon Aug 30, 2004 6:55 am
Location: Germany, Cologne

Re: Version Info in runtime

Postby upCASE » Wed May 17, 2006 7:19 am

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/versioninfo/article.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

Postby Tobi » Wed May 17, 2006 8:53 am

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

  [SOLVED]

Postby HeReSY » Wed May 17, 2006 10:41 am

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
Site Admin
Site Admin
Posts: 3176
Joined: Mon Aug 30, 2004 6:55 am
Location: Germany, Cologne

Postby upCASE » Wed May 17, 2006 10:58 am

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

Postby Tobi » Thu May 18, 2006 9:36 am

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

Postby Tobi » Thu May 18, 2006 9:39 am

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
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 249
Joined: Thu Jun 01, 2006 4:36 pm
Location: Right here!

Re: Version Info in runtime

Postby Widgets » Fri Apr 22, 2016 11:25 pm

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 64-bit
MSVC Express 2010 & 2015
wxWidgets 3.1
Fight SPAM - report it with wxSR


Return to “wxDev-C++”

Who is online

Users browsing this forum: No registered users and 2 guests