自从Windows 8.1废弃了GetVersionEx,必须写manifest才能正确获取系统版本之后,如何始终正确获取系统版本就是一个让人头疼的话题。大概有以下几种尝试。
实际上,有一种方法微软可能懒得造假,那就是VerQueryValue读取kernel32.dll等系统文件的产品版本号dwProductVersionMS/LS。有人可能会说,那以后微软不在这里写系统版本了怎么办?实际上,微软已经公开了这个做法,将来不可能大改,否则将有兼容性问题。
XXXXXXXXXXXXXXXXXXXXXXXXXX/en-us/library/windows/desktop/ms724429(v=vs.85).aspx
一般来说,系统文件版本号的格式是XXXXXXXXXXXXXXXXXXXXv。不过,已淘汰的Windows 95/98/Me并不遵守这个约定,它们的系统文件版本号是major.minor.0.build。不过,可以通过dwFileOS是否设置有VOS_DOS位来判断Windows 95/98/Me,而且它们的版本号都是4.x,现在的操作系统版本号早已超过5.0。
不建议读取dwFileVersionMS/LS,它是kernel32.dll文件本身的版本号,而不是系统的版本号。
为了保证可靠,这里也不推荐使用GetFileVersionInfo,因为Windows也可以在这个函数上做手脚。建议直接读取已加载的kernel32.dll模块的资源段,方法如下:
<code class="language-cpp">#include <windows.h> #include <tchar.h> #pragma comment(lib, "version.lib") BOOL CheckModuleProductVersion(LPCTSTR modname, WORD major, WORD minor, WORD build, WORD rev) { HMODULE hmod = GetModuleHandle(modname); if (!hmod) return FALSE; LPVOID verblock = LockResource(LoadResource(hmod, FindResource(hmod, MAKEINTRESOURCE(1), MAKEINTRESOURCE(RT_VERSION)))); if (!verblock) return FALSE; VS_FIXEDFILEINFO *pvsffi = NULL; UINT szvsffi = 0; if (!VerQueryValue(verblock, _T("\\"), (LPVOID*)&pvsffi, &szvsffi)) return FALSE; ULONGLONG ullProductVersion = ((ULONGLONG)pvsffi->dwProductVersionMS << 32) + pvsffi->dwProductVersionLS; ULONGLONG ullReqVersion = ((ULONGLONG)major << 48) + ((ULONGLONG)minor << 32) + ((ULONGLONG)build << 16) + rev; if (ullProductVersion < ullReqVersion) return FALSE; return TRUE; } BOOL GetOSVersion(PULONGLONG pullProductVersion, PBOOL piswin9x) { #pragma comment(lib, "version.lib") HMODULE hmod = GetModuleHandle(_T("kernel32.dll")); if (!hmod) return FALSE; LPVOID verblock = LockResource(LoadResource(hmod, FindResource(hmod, MAKEINTRESOURCE(1), MAKEINTRESOURCE(RT_VERSION)))); if (!verblock) return FALSE; VS_FIXEDFILEINFO *pvsffi = NULL; UINT szvsffi = 0; if (!VerQueryValue(verblock, _T("\\"), (LPVOID*)&pvsffi, &szvsffi)) return FALSE; if (pullProductVersion) *pullProductVersion = ((ULONGLONG)pvsffi->dwProductVersionMS << 32) + pvsffi->dwProductVersionLS; if (piswin9x) *piswin9x = !!(pvsffi->dwFileOS & VOS_DOS); return TRUE; } BOOL Is_Win7_OrGreater() { ULONGLONG osver = 0; if (!GetOSVersion(&osver, NULL)) return FALSE; return osver >= (6UI64 << 48) + (1UI64 << 32); } </tchar.h></windows.h></code>
[修改于 7年8个月前 - 2017/05/01 02:40:15]
时段 | 个数 |
---|---|
{{f.startingTime}}点 - {{f.endTime}}点 | {{f.fileCount}} |