typedef struct tagTRANSLATION
{
WORD langID; // language ID
WORD charset; // character set (code page)
} TRANSLATION;
#define KeyFILENAMECHECK "\\kernel32.dll"
DWORD GetVersionExFromFile(OSVERSIONINFOEX &osvi)
{
BOOL bOsVersionInfoEx;
TCHAR szSysDir[MAX_PATH] = {0};
TCHAR szFileName[MAX_PATH+sizeof(KeyFILENAMECHECK)] = {0};
TRANSLATION translation;
DWORD dwDummyHandle;
DWORD len = 0;
BYTE *pVerBuf = NULL;
LPVOID pInfoVal;
unsigned int dwInfoValSize;
char INFO[MAX_PATH] = {0};
int iMajorVer, iMinorVer;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if ((bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*)&osvi)) == 0)
{
// If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO.
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
if (!GetVersionEx((OSVERSIONINFO *)&osvi))
{
return FALSE;
}
}
// 通过关键系统文件判断正确的操作系统版本
GetSystemDirectory(szSysDir, MAX_PATH);
_snprintf(szFileName, sizeof(szFileName) - 1, "%s%s", szSysDir, KeyFILENAMECHECK);
//将版本信息资源读入缓冲区
len = GetFileVersionInfoSize(szFileName, &dwDummyHandle);
if (len > 0)
{
pVerBuf = (BYTE *)LocalAlloc(LHND, len);
}
if (pVerBuf
&& GetFileVersionInfo(szFileName, 0, len, pVerBuf))
{
translation.langID = MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US);
if (VerQueryValue(pVerBuf,
TEXT("\\VarFileInfo\\Translation"),
&pInfoVal, &dwInfoValSize)
&& dwInfoValSize >= 4)
{
translation = *(TRANSLATION*)pInfoVal;
}
_snprintf(INFO,
sizeof(INFO) - 1,
"\\StringFileInfo\\%04x%04x\\FileVersion",
translation.langID,
translation.charset);
//获得具体的版本号
VerQueryValue(pVerBuf, (LPSTR)INFO, &pInfoVal, &dwInfoValSize);
iMajorVer = *((char*)pInfoVal) - '0';
iMinorVer = *((char*)pInfoVal + 2) - '0';
// 取文件版本成功则使用文件版本,此处也可判断是否运行在兼容模式下
osvi.dwMajorVersion = iMajorVer;
osvi.dwMinorVersion = iMinorVer;
}
if (pVerBuf)
{
memset(pVerBuf, 0, len);
LocalFree(pVerBuf);
}
return TRUE;
}
int main()
{
OSVERSIONINFOEX osvi;
GetVersionExFromFile(osvi);
return 0;
}