当前位置:  开发笔记 > 编程语言 > 正文

如何从Visual C++中的版本资源中读取

如何解决《如何从VisualC++中的版本资源中读取》经验,为你挑选了5个好方法。

我在C++项目的资源中有一个版本资源,其中包含版本号,版权和构建详细信息.是否有一种简单的方法可以在运行时访问它以填充我的帮助/关于对话框,因为我目前正在维护此信息的单独const值.理想情况下,该解决方案应适用于Windows/CE移动版和早期版本的Visual C++(6.0以上版本).



1> Mark Ransom..:

这是我原来答案的编辑版本.

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 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;
}


@Mark:你说得对.它没有很好的记录.我试图找到,为什么我的字符串连接不起作用.它在代码中处于完全不同的位置.最后,我将其追溯到`VerQueryValue`函数.在那里我突然意识到字符串数据中可能还有一个零.修剪它,瞧它工作了.也许你只是在你的解决方案中提示,让人们看看我的评论.如果您只是单独使用字符串,您将不会注意到差异.只要你`+ =`另一个字符串或使用`+`运算符,症状就会显示出来.

2> 小智..:

为了获得与马克答案变化无关的语言结果:

   // 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;
}

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));


这可以从马克·兰瑟姆的答案中获得不同的信息。您检索的值是资源文件中PRODUCTVERSION顶层行中的四个整数;但是Marks的答案是从“ StringFileInfo”块下面检索字符串“ ProductVersion”。

3> Will Dean..:

也许会让你开始的事情:

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("\\"), (LPVOID*)&pFixInfo, &length));



4> Rob..:

这样的事情将为您提供对资源数据的原始访问并让您入门:

HRSRC res = ::FindResource(NULL, MAKEINTRESOURCE(MY_VERSION_ID), RT_VERSION);
DWORD size = ::SizeofResource(NULL, res);
HGLOBAL mem = ::LoadResource(NULL, res);
LPVOID raw_data = ::LockResource(mem);
...
::FreeResource(mem);



5> 小智..:

谨防!使用FindResource..LockResource不正确。它有时会工作(就像在我的小型演示程序中一样),有时会导致访问冲突(例如:我正在为其制作演示的生产代码)。

VerQueryValue()文档指出,应改为调用GetFileVersionInfoSize和GetFileVersionInfo。雷蒙德·陈(Raymond Chen)解释,请参见http://blogs.msdn.com/oldnewthing/archive/2006/12/26/1365215.aspx

推荐阅读
路人甲
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有