如何从资源中获取版本信息? [英] How to get version info from resources?

查看:74
本文介绍了如何从资源中获取版本信息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在资源中声明了版本信息:

I have the Version Info in resources declared:

100 VERSIONINFO
FILEVERSION 1,0,0,2
PRODUCTVERSION 1,0,0,2
FILEOS VOS_NT
FILETYPE VFT_APP
{
    BLOCK "StringFileInfo"
    {
        BLOCK "000004b0"
        {
            VALUE "FileDescription", "My application"
            VALUE "FileVersion", "1.0.0.2"
            VALUE "InternalName", "app.exe"
            VALUE "LegalCopyright", "Copyright ©  2012 by David."
            VALUE "OriginalFilename", "app.exe"
            VALUE "ProductName", "app"
            VALUE "ProductVersion", "1.0.0.2"
            VALUE "Assembly Version", "1.0.0.2"
        }
    }

    BLOCK "VarFileInfo"
    {
        VALUE "Translation", 0x0000 0x04B0
    }
}

我通过这种方式获取版本信息:

I am getting Version Info this way:

HRSRC hResInfo;
HGLOBAL hResData;
LPCVOID pRes;
UINT uLen;
VS_FIXEDFILEINFO *lpFfi;

hResInfo = FindResource(hInst, MAKEINTRESOURCE(100), RT_VERSION);
MessageBox(0, "FindResource", 0,0);

hResData = LoadResource(hInst, hResInfo);
MessageBox(0, "LoadResource", 0,0);

pRes = LockResource(hResData);
MessageBox(0, "LockResource", 0,0);

VerQueryValue(pRes, "\\" ,(LPVOID*)&lpFfi, &uLen);
MessageBox(0, "VerQueryValue", 0,0);

FreeResource(hResData);

DWORD dwFileVersionMS = lpFfi->dwFileVersionMS;
DWORD dwFileVersionLS = lpFfi->dwFileVersionLS;

DWORD dwLeftMost     = HIWORD(dwFileVersionMS);
DWORD dwSecondLeft   = LOWORD(dwFileVersionMS);
DWORD dwSecondRight  = HIWORD(dwFileVersionLS);
DWORD dwRightMost    = LOWORD(dwFileVersionLS);

在函数 VerQueryValue 中是一个错误,因为程序中断(带有文本VerQueryValue"的 MessageBox 不显示)并且 Visual C++ 向我显示以下消息:

In function VerQueryValue is an error, because program breaks (MessageBox with text "VerQueryValue" doesn't show) and Visual C++ shows me the following message:

ProxyCU.exe 中 0x77bf15a5 处的第一次机会异常:0xC0000005:访问冲突写入位置 0x00483192.

First-chance exception at 0x77bf15a5 in ProxyCU.exe: 0xC0000005: Access violation writing location 0x00483192.

如何修复此代码?

问候,大卫

推荐答案

VerQueryValue() 无法直接从原始资源访问版本信息.您必须在内存中复制资源,然后将该内存传递给 VerQueryValue().原因是因为 VerQueryValue() 旨在与 GetFileVersionInfo() 一起使用,这需要用户分配的可写内存块并在该内存中执行某些修复.访问 VS_FIXEDFILEINFO 结构不需要修正,但内存块必须仍然是可写的.您不能将原始资源直接传递给 VerQueryValue(),因为它是只读内存.

VerQueryValue() cannot access version info from the original resource directly. You must make a copy of the resource in memory, then pass that memory to VerQueryValue() instead. The reason is because VerQueryValue() is designed to work with GetFileVersionInfo(), which requires a user-allocated block of writable memory and performs certain fixups within that memory. Accessing the VS_FIXEDFILEINFO struct does not require the fixups, but the memory block must still be writable. You cannot pass the original resource directly to VerQueryValue() because it is read-only memory.

试试这个:

HRSRC hResInfo;
DWORD dwSize;
HGLOBAL hResData;
LPVOID pRes, pResCopy;
UINT uLen;
VS_FIXEDFILEINFO *lpFfi;

hResInfo = FindResource(hInst, MAKEINTRESOURCE(100), RT_VERSION);
dwSize = SizeofResource(hInst, hResInfo);
hResData = LoadResource(hInst, hResInfo);
pRes = LockResource(hResData);
pResCopy = LocalAlloc(LMEM_FIXED, dwSize);
CopyMemory(pResCopy, pRes, dwSize);
FreeResource(hResData);

VerQueryValue(pResCopy, TEXT("\\"), (LPVOID*)&lpFfi, &uLen);

DWORD dwFileVersionMS = lpFfi->dwFileVersionMS;
DWORD dwFileVersionLS = lpFfi->dwFileVersionLS;

DWORD dwLeftMost     = HIWORD(dwFileVersionMS);
DWORD dwSecondLeft   = LOWORD(dwFileVersionMS);
DWORD dwSecondRight  = HIWORD(dwFileVersionLS);
DWORD dwRightMost    = LOWORD(dwFileVersionLS);

LocalFree(pResCopy);

更新:这仅在您访问 VS_FIXEDFILEINFO 结构时才有效.如果您需要访问任何其他值,则必须使用 GetFileVersionInfo().根据 Raymond Chen 的博客:

UPDATE: this only works if you access the VS_FIXEDFILEINFO struct only. If you need to access any other values, you must use GetFileVersionInfo(). Per Raymond Chen's blog:

VerQueryValue 的第一个参数确实必须是您从 GetFileVersionInfo 获得的缓冲区

文档说 VerQueryValue 的第一个参数必须是 GetFileVersionInfo 函数返回的缓冲区,这是有原因的.GetFileVersionInfo 返回的缓冲区是一个专门格式化的不透明数据块,以便 VerQueryValue 可以工作.您不应该查看该缓冲区的内部,当然也不能尝试以其他方式获取数据".因为如果您这样做,VerQueryValue 将在缓冲区中查找未按函数预期方式格式化的内容.

The documentation says that the first parameter to VerQueryValue must be a buffer returned by the GetFileVersionInfo function for a reason. The buffer returned by GetFileVersionInfo is an opaque data block specifically formatted so that VerQueryValue will work. You're not supposed to look inside that buffer, and you certainly can't try to "obtain the data some other way". Because if you do, VerQueryValue will look for something in a buffer that is not formatted in the manner the function expects.

这篇关于如何从资源中获取版本信息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆