Question : MFC VersionInfo problem

I am writing a simple window based dialog that I will show a list of files and allow you to retrieve the version resource information.  I have a class that I pulled off the web called CVersionInfo but I can not seem to get it to work.  I understand that the versioninfo struct is a UNICODE structure and this is where my problem lies.  The file is found, the VersionInfo Struct is populated but the Quickwatch shows the CString values with the a . which equates to the 00 value in the memory watch.  It would appear that the strings are not being converted to Unicode correctly.  When you look at each individual string, the tool tip and the watch value only shows the first character.  It seems like it is a trivial problem, I just don't deal with UNICODE so I do not know how to fix it.

 The code snippet is below

#include "stdafx.h"
#include "version.h"
#include "cversion.h"
#include "string.h"

CVersionInfo::CVersionInfo(LPCSTR szFileToVersion /* = NULL*/,
                                                   LPCSTR szLanguage /* = "0409"*/,
                                                   LPCSTR szCodepage /* = "04e4"*/)
{
        m_lpstrVffInfo = NULL;
        m_strFileName = szFileToVersion;
        m_strLanguage = szLanguage;
        m_strCodepage = szCodepage;
        m_strCompanyName = _T("");
        m_strFileDescription  = _T("");
        m_strFileVersion = _T("");
        m_strInternalName = _T("");
        m_strLegalCopyright = _T("");
        m_strOriginalFilename = _T("");
        m_strProductName = _T("");
        m_strProductVersion = _T("");
        m_strComments = _T("");
        m_strSpecialBuild = _T("");
        m_strPrivateBuild = _T("");
        m_bQueryDone=FALSE;
}

CString CVersionInfo::GetFileVersion()
{
        if (!m_bQueryDone)
                GetVersionInfo();
        return m_strFileVersion;
}

CString CVersionInfo::GetPrivateBuild()
{
        if (!m_bQueryDone)
                GetVersionInfo();
        return m_strPrivateBuild;
}

CString CVersionInfo::GetSpecialBuild()
{
        if (!m_bQueryDone)
                GetVersionInfo();
        return m_strSpecialBuild;
}

CString CVersionInfo::GetCompanyName()
{
        if (!m_bQueryDone)
                GetVersionInfo();
        return m_strCompanyName;
}

CString CVersionInfo::GetFileDescription()
{
        if (!m_bQueryDone)
                GetVersionInfo();
        return m_strFileDescription;
}

CString CVersionInfo::GetInternalName()
{
        if (!m_bQueryDone)
                GetVersionInfo();
        return m_strInternalName;
}

CString CVersionInfo::GetLegalCopyright()
{
        if (!m_bQueryDone)
                GetVersionInfo();
        return m_strLegalCopyright;
}

CString CVersionInfo::GetOriginalFilename()
{
        if (!m_bQueryDone)
                GetVersionInfo();
        return m_strOriginalFilename;
}

CString CVersionInfo::GetProductVersion()
{
        if (!m_bQueryDone)
                GetVersionInfo();
        return m_strProductVersion;
}

CString CVersionInfo::GetComments()
{
        if (!m_bQueryDone)
                GetVersionInfo();
        return m_strComments;
}

void CVersionInfo::GetVersionInfo()
{
        DWORD   dwVerInfoSize;          // Size of version information block
        DWORD   dwVerHnd=0;                     // An 'ignored' parameter, always '0'
        WCHAR szFileName[MAX_PATH];

        m_bQueryDone=TRUE;
        if (m_strFileName.IsEmpty())
                GetModuleFileName(NULL, szFileName, MAX_PATH);
        else
                lstrcpy(szFileName, m_strFileName);
       
        dwVerInfoSize = GetFileVersionInfoSize(szFileName, &dwVerHnd);
        if (dwVerInfoSize) {
                HANDLE  hMem;
                hMem = GlobalAlloc(GMEM_MOVEABLE, dwVerInfoSize);
                m_lpstrVffInfo  = (char *)GlobalLock(hMem);
                GetFileVersionInfo(szFileName, dwVerHnd, dwVerInfoSize, m_lpstrVffInfo);
                QueryValue("CompanyName", m_strCompanyName);
                QueryValue("FileDescription", m_strFileDescription);
                QueryValue("FileVersion", m_strFileVersion);
                QueryValue("InternalName", m_strInternalName);
                QueryValue("LegalCopyright", m_strLegalCopyright);
                QueryValue("OriginalFilename", m_strOriginalFilename);
                QueryValue("ProductName", m_strProductName);
                QueryValue("ProductVersion", m_strProductVersion);
                QueryValue("Comments", m_strComments);
                QueryValue("SpecialBuild", m_strSpecialBuild);
                QueryValue("PrivateBuild", m_strPrivateBuild);
                GlobalUnlock(hMem);
                GlobalFree(hMem);
        }
}

void CVersionInfo::QueryValue(LPCSTR szId, CString& s)
{
        ASSERT(m_lpstrVffInfo != NULL);
        LPSTR   lpVersion;                      // String pointer to 'version' text
        UINT    uVersionLen;
        BOOL    bRetCode;

        CString szSelector;  
            
            CString stringfileinfo ="\\StringFileInfo\\";
        szSelector= stringfileinfo + m_strLanguage + m_strCodepage + "\\" + szId;
        bRetCode = VerQueryValue((LPVOID)m_lpstrVffInfo,
                szSelector.GetBuffer(szSelector.GetLength()),
                (LPVOID *)&lpVersion,
                &uVersionLen);
       
        if(bRetCode)
                s = lpVersion;
        else
                s.Empty();
}


My question is how to handle this so I get the correct data in the CStrings?

Scot

Answer : MFC VersionInfo problem

here is the code I use .. try it out:

NOTE: this is hard code for the language I want .. feel free to fiddle with it.  Also, I use different member var names than you do and I also get file/product version numbers into int arrays m_fv, m_pv.

CString CVersionInfo::GetVersionInfoField (CString name, void* bufVersionInfo, WORD* pLanguage) const {
      CString key;
      key.Format("\\StringFileInfo\\%04X%04x\\%s",*((WORD*)pLanguage),*(((WORD*)pLanguage)+1),name);
      UINT ulen;
      char* bufString;
      if (! ::VerQueryValue(bufVersionInfo, const_cast(LPCTSTR(key)), reinterpret_cast(&bufString), &ulen)) return afxEmptyString;
      return CString(bufString, ulen+1);
}

void CVersionInfo::GetVersionInfo (CString filename) const {
      char* path = const_cast(LPCTSTR(filename));
      
      DWORD hVerDummy;
      DWORD dwVersionInfoSize = ::GetFileVersionInfoSize(path,&hVerDummy);
      if (dwVersionInfoSize == 0L) return;
      
      void* bufVersionInfo = malloc(dwVersionInfoSize);
      if (! bufVersionInfo) return;
      
      if (::GetFileVersionInfo(path,hVerDummy,dwVersionInfoSize,bufVersionInfo)) {
            UINT ulen;
            
            // Get Version Info
            VS_FIXEDFILEINFO *bufFixedFileInfo;
            if (::VerQueryValue(bufVersionInfo,"\\",reinterpret_castVOID*>(&bufFixedFileInfo), &ulen)){
                  m_fv[0] = HIWORD(bufFixedFileInfo->dwFileVersionMS);
                  m_fv[1] = LOWORD(bufFixedFileInfo->dwFileVersionMS);
                  m_fv[2] = HIWORD(bufFixedFileInfo->dwFileVersionLS);
                  m_fv[3] = LOWORD(bufFixedFileInfo->dwFileVersionLS);
                  m_pv[0] = HIWORD(bufFixedFileInfo->dwProductVersionMS);
                  m_pv[1] = LOWORD(bufFixedFileInfo->dwProductVersionMS);
                  m_pv[2] = HIWORD(bufFixedFileInfo->dwProductVersionLS);
                  m_pv[3] = LOWORD(bufFixedFileInfo->dwProductVersionLS);
            }
            
            WORD* pLanguage;
            if(::VerQueryValue(bufVersionInfo, "\\VarFileInfo\\Translation", reinterpret_cast(&pLanguage), &ulen) && ulen != 0) {
                  m_Comments = GetVersionInfoField ("Comments",bufVersionInfo,pLanguage);
                  m_CompanyName = GetVersionInfoField ("CompanyName",bufVersionInfo,pLanguage);
                  m_FileDescription = GetVersionInfoField ("FileDescription",bufVersionInfo,pLanguage);
                  m_InternalName = GetVersionInfoField ("InternalName",bufVersionInfo,pLanguage);
                  m_LegalCopyright = GetVersionInfoField ("LegalCopyright",bufVersionInfo,pLanguage);
                  m_LegalTrademarks = GetVersionInfoField ("LegalTrademarks",bufVersionInfo,pLanguage);
                  m_OriginalFilename = GetVersionInfoField ("OriginalFilename",bufVersionInfo,pLanguage);
                  m_PrivateBuild = GetVersionInfoField ("PrivateBuild",bufVersionInfo,pLanguage);
                  m_ProductName = GetVersionInfoField ("ProductName",bufVersionInfo,pLanguage);
                  m_SpecialBuild = GetVersionInfoField ("SpecialBuild",bufVersionInfo,pLanguage);
            }      
      }
      free(bufVersionInfo);
}

Random Solutions  
 
programming4us programming4us