I am trying to get version information from a file. My code works perfectly for me, but fails on several others' machines. Because I can't reproduce the bug, I'm having quite a time finding the issue.
我试图从文件中获取版本信息。我的代码对我来说很完美,但在其他几台机器上却失败了。因为我无法重现这个bug,所以我有很多时间找到这个问题。
Does anyone see anything majorly wrong with this?
有人看到这个有什么重大错误吗?
LPBYTE versionInformationBlock;
struct LANGANDCODEPAGE {
WORD wLanguage;
WORD wCodePage;
} *langBlockPointer;
UINT translationsCount;
void fileData::enumVersionInformationBlock()
{
bits.set(VERSIONINFOCHECKED);
disable64.disableFS(); //Shut down WOW64
DWORD zero = 0;
DWORD lengthOfVersionData =
GetFileVersionInfoSize(getFileName().c_str(),&zero);
if (!lengthOfVersionData)
{
disable64.enableFS();
return;
}
versionInformationBlock = new BYTE[lengthOfVersionData];
GetFileVersionInfo(getFileName().c_str(),zero,lengthOfVersionData,versionInformationBlock);
VerQueryValue(versionInformationBlock,L"\\VarFileInfo\\Translation",(LPVOID*)&langBlockPointer,&translationsCount);
translationsCount /= sizeof(struct LANGANDCODEPAGE);
disable64.enableFS();
}
std::wstring fileData::getVersionInformationString(const std::wstring& str)
{
if (!bits[VERSIONINFOCHECKED])
enumVersionInformationBlock();
if (!versionInformationBlock)
return L"!VERINFO: NOT PE FILE!";
LPCTSTR retString;
UINT retStringLength;
std::wstring result;
static const wchar_t hexChars[] = L"0123456789ABCDEF";
wchar_t hexLanguage[26] = L"\\StringFileInfo\\ \\";
for( size_t idx = 0; idx < translationsCount; idx++ )
{
hexLanguage[16] = *(hexChars + ((langBlockPointer[idx].wLanguage >> 12) & 0x0F));
hexLanguage[17] = *(hexChars + ((langBlockPointer[idx].wLanguage >> 8 ) & 0x0F));
hexLanguage[18] = *(hexChars + ((langBlockPointer[idx].wLanguage >> 4 ) & 0x0F));
hexLanguage[19] = *(hexChars + ( langBlockPointer[idx].wLanguage & 0x0F));
hexLanguage[20] = *(hexChars + ((langBlockPointer[idx].wCodePage >> 12) & 0x0F));
hexLanguage[21] = *(hexChars + ((langBlockPointer[idx].wCodePage >> 8 ) & 0x0F));
hexLanguage[22] = *(hexChars + ((langBlockPointer[idx].wCodePage >> 4 ) & 0x0F));
hexLanguage[23] = *(hexChars + ( langBlockPointer[idx].wCodePage & 0x0F));
std::wstring targetResource(hexLanguage,25);
targetResource.append(str);
if (!VerQueryValue(versionInformationBlock,targetResource.c_str(),(LPVOID *)&retString,&retStringLength))
{
return std::wstring(L"!DOESN'T APPER TO EXIST IN FILE! ERROR: ").append(boost::lexical_cast<std::wstring>(GetLastError()));
}
retStringLength--;
if (!result.empty())
result.append(L" / ");
std::wstring toAppend;
toAppend.assign(retString,retStringLength);
boost::algorithm::trim(toAppend);
result.append(toAppend);
}
return result;
}
std::wstring fileData::getVerCompany()
{
return getVersionInformationString(L"CompanyName");
}
~fileData()
{
if (versionInformationBlock)
delete [] versionInformationBlock;
};
What's really bugging me is that it isn't throwing any of my error messages... it keeps returning garbage.
真正让我烦恼的是,它不会抛出我的任何错误信息......它会不断回收垃圾。
Any ideas?
Billy3
3 个解决方案
#1
Try the following:
请尝试以下方法:
- Retrieve the reason for
GetFileVersion
's failure by usingGetLastError
- Tell us what OS it works on and what OS it doesn't
- Check if
GetFileVersionInfo
succeeds or not (againGetLastError
) - Read the Remarks section of the MSDN documentation of the abovementioned functions repeatedly and check if you are not missing something.
使用GetLastError检索GetFileVersion失败的原因
告诉我们它运行的操作系统以及它没有的操作系统
检查GetFileVersionInfo是否成功(再次GetLastError)
重复阅读上述功能的MSDN文档的备注部分,检查您是否遗漏了某些内容。
#2
It looks like you are not checking for errors from many of the system calls you are using. For example, GetFileVersionInfo
will return zero if there is an error getting the data, at which point you can call GetLastError
to find out what the specific failure was. Likewise, GetFileVersionInfoSize
will return zero if there is an error. It looks like you check for that failure but don't bother to log the system error code (again, use GetLastError
to retrieve that value).
看起来您没有检查您正在使用的许多系统调用中的错误。例如,如果获取数据时出错,GetFileVersionInfo将返回零,此时您可以调用GetLastError来查找特定故障的内容。同样,如果出现错误,GetFileVersionInfoSize将返回零。看起来你检查了那个失败但是没有麻烦记录系统错误代码(再次,使用GetLastError来检索该值)。
I suggest you add the error handling code for the system calls you are using. Most likely one of those is failing, and probably leaving a very meaningful error code for you to inspect with GetLastError
.
我建议您为正在使用的系统调用添加错误处理代码。很可能其中一个是失败的,并且可能留下一个非常有意义的错误代码供您使用GetLastError进行检查。
#3
nvm. Seems * beats the heck out of me if it isn't answered.....
NVM。如果没有回答,似乎*击败了我......
Billy3
#1
Try the following:
请尝试以下方法:
- Retrieve the reason for
GetFileVersion
's failure by usingGetLastError
- Tell us what OS it works on and what OS it doesn't
- Check if
GetFileVersionInfo
succeeds or not (againGetLastError
) - Read the Remarks section of the MSDN documentation of the abovementioned functions repeatedly and check if you are not missing something.
使用GetLastError检索GetFileVersion失败的原因
告诉我们它运行的操作系统以及它没有的操作系统
检查GetFileVersionInfo是否成功(再次GetLastError)
重复阅读上述功能的MSDN文档的备注部分,检查您是否遗漏了某些内容。
#2
It looks like you are not checking for errors from many of the system calls you are using. For example, GetFileVersionInfo
will return zero if there is an error getting the data, at which point you can call GetLastError
to find out what the specific failure was. Likewise, GetFileVersionInfoSize
will return zero if there is an error. It looks like you check for that failure but don't bother to log the system error code (again, use GetLastError
to retrieve that value).
看起来您没有检查您正在使用的许多系统调用中的错误。例如,如果获取数据时出错,GetFileVersionInfo将返回零,此时您可以调用GetLastError来查找特定故障的内容。同样,如果出现错误,GetFileVersionInfoSize将返回零。看起来你检查了那个失败但是没有麻烦记录系统错误代码(再次,使用GetLastError来检索该值)。
I suggest you add the error handling code for the system calls you are using. Most likely one of those is failing, and probably leaving a very meaningful error code for you to inspect with GetLastError
.
我建议您为正在使用的系统调用添加错误处理代码。很可能其中一个是失败的,并且可能留下一个非常有意义的错误代码供您使用GetLastError进行检查。
#3
nvm. Seems * beats the heck out of me if it isn't answered.....
NVM。如果没有回答,似乎*击败了我......
Billy3