How do I read from a version resource in Visual C++

前端 未结 7 403
情歌与酒
情歌与酒 2020-11-28 09:17

I have a version resource in my resources in a C++ project which contains version number, copyright and build details. Is there an easy way to access this at run-time to po

相关标签:
7条回答
  • 2020-11-28 09:45

    To get a language independent result to Mark's answer change :

       // replace "040904e4" with the language ID of your resources
        !VerQueryValue(&data[0], _T("\\StringFileInfo\\040904e4\\ProductVersion"), &pvProductVersion, &iProductVersionLen))
    {
        TRACE("Can't obtain ProductName and ProductVersion from resources\n");
        return false;
    }
    

    To

    UINT                uiVerLen = 0;
    VS_FIXEDFILEINFO*   pFixedInfo = 0;     // pointer to fixed file info structure
    // get the fixed file info (language-independent) 
    if(VerQueryValue(&data[0], TEXT("\\"), (void**)&pFixedInfo, (UINT *)&uiVerLen) == 0)
    {
        return false;
    }
    
     strProductVersion.Format("%u.%u.%u.%u", 
        HIWORD (pFixedInfo->dwProductVersionMS),
        LOWORD (pFixedInfo->dwProductVersionMS),
        HIWORD (pFixedInfo->dwProductVersionLS),
        LOWORD (pFixedInfo->dwProductVersionLS));
    
    0 讨论(0)
  • 2020-11-28 09:49

    Ok, a bit more googleing found the following on CodeGuru. Basically this approach uses the CFileVersionInfo object to get on any given file. It should be interesting to see if it works on the currently running .EXE file and on Windows CE.

    0 讨论(0)
  • 2020-11-28 09:50

    This is an edited version of my original answer.

    bool GetProductAndVersion(CStringA & strProductName, CStringA & strProductVersion)
    {
        // get the filename of the executable containing the version resource
        TCHAR szFilename[MAX_PATH + 1] = {0};
        if (GetModuleFileName(NULL, szFilename, MAX_PATH) == 0)
        {
            TRACE("GetModuleFileName failed with error %d\n", GetLastError());
            return false;
        }
    
        // allocate a block of memory for the version info
        DWORD dummy;
        DWORD dwSize = GetFileVersionInfoSize(szFilename, &dummy);
        if (dwSize == 0)
        {
            TRACE("GetFileVersionInfoSize failed with error %d\n", GetLastError());
            return false;
        }
        std::vector<BYTE> data(dwSize);
    
        // load the version info
        if (!GetFileVersionInfo(szFilename, NULL, dwSize, &data[0]))
        {
            TRACE("GetFileVersionInfo failed with error %d\n", GetLastError());
            return false;
        }
    
        // get the name and version strings
        LPVOID pvProductName = NULL;
        unsigned int iProductNameLen = 0;
        LPVOID pvProductVersion = NULL;
        unsigned int iProductVersionLen = 0;
    
        // replace "040904e4" with the language ID of your resources
        if (!VerQueryValue(&data[0], _T("\\StringFileInfo\\040904e4\\ProductName"), &pvProductName, &iProductNameLen) ||
            !VerQueryValue(&data[0], _T("\\StringFileInfo\\040904e4\\ProductVersion"), &pvProductVersion, &iProductVersionLen))
        {
            TRACE("Can't obtain ProductName and ProductVersion from resources\n");
            return false;
        }
    
        strProductName.SetString((LPCSTR)pvProductName, iProductNameLen);
        strProductVersion.SetString((LPCSTR)pvProductVersion, iProductVersionLen);
    
        return true;
    }
    
    0 讨论(0)
  • 2020-11-28 09:56

    Sometimes I receive Access Violation when use VerQueryValueA. But I never got this error when use VerQueryValueW. I think something wrong with VerQueryValueA in version.dll. Therefore I use VerQueryValueW instead of VerQueryValueA even in projects Multi-byte Character Encoding. Here is my code of ReadVersion function

    0 讨论(0)
  • 2020-11-28 09:57

    Beware! Using FindResource..LockResource is not correct. It will sometimes work (as it did in my small demo program) and sometimes cause access violations (example: the production code I was making the demo for).

    The VerQueryValue() documentation states that you should call GetFileVersionInfoSize and GetFileVersionInfo instead. Raymond Chen explains, see http://blogs.msdn.com/oldnewthing/archive/2006/12/26/1365215.aspx

    0 讨论(0)
  • 2020-11-28 09:58

    Something like might get you started, perhaps:

    TCHAR moduleName[MAX_PATH+1];
    (void)GetModuleFileName(AfxGetInstanceHandle(), moduleName, MAX_PATH);
    DWORD dummyZero;
    DWORD versionSize = GetFileVersionInfoSize(moduleName, &dummyZero);
    if(versionSize == 0)
    {
        return NULL;
    }
    void* pVersion = malloc(versionSize);
    if(pVersion == NULL)
    {
        return NULL;
    }
    if(!GetFileVersionInfo(moduleName, NULL, versionSize, pVersion))
    {
        free(pVersion);
        return NULL;
    }
    
    UINT length;
    VS_FIXEDFILEINFO* pFixInfo;
    VERIFY(VerQueryValue(pVersionInfo, const_cast<LPTSTR>("\\"), (LPVOID*)&pFixInfo, &length));
    
    0 讨论(0)
提交回复
热议问题