获取Windows 10版本信息

自从Windows 8.1 (包括Windows 10)之后,原有的GetVersion和GetVersionEx就没法返回正确的Windows版本信息了。按照Microsoft上的介绍来讲:希望开发不是用系统的版本号来进行功能的开发,而是希望开发者用类似Feature Detection的方式来进行开发。虽然这个想法很美好,但是为了能向下兼容,有时候还是需要获取到当前Windows的详细的版本信息。
网络上常见的方式是通过嵌入Manifest, 然后指定兼容的WIndows版本让GetVersion这一系列的函数能返回正确的版本信息。但这个方法感觉太过麻烦,即使没有升级内容,也需要根据不同版本的Windows来对Manifest进行升级。下面介绍两种不同过Manifest的方法来获取到正确的Windows版本信息。

  • WMI
    WMI 提供了丰富的接口来获取各种系统信息,当然其中包括了获取系统版本信息,而且这种方法不受版本的限制, 我测试了Windows XP、Windows 7、Windows 10 都可以正确获取。本来想贴上代码,但是代码有点儿长,还是放上两个连接,如果需要直接看这个两个例子就可以了。
    How to Find the Windows Version From Powershell Command Line
    Getting WMI Data from the Local Computer (MSDN)
    将MSDN的例子中的 Name 换成 Version 即可。

  • Kernel32.dll
    经过实际测试,这个办法在Windows 10 上是无效的,Kernel32.dll的版本和GetVersion得到的内容是一致的。所以,最后还是用WMI来的实在。
    [2017-01-24 更新] 昨天因为某些原因又和同事讨论了这个问题。当时QA的同事也说到了这个方法。我说这个方法是无效的,当时已经测试过了。但是因为各自都相信自己的经验,于是就又测试了一遍,最后发现这个方法竟然又好用了。仔细回想可能是因为当时测试的时候是在Windows 10 Preview上进行的测试,Preview的Product Version并没有像RTM版本一样进行了更新。这也是一个经验吧,以后一切的测试都要以RTM为基准。
    这个方法也是偶然看到别人提出的,试验了一下,也是个不错的方法。Kernel32.dll的File Version和 Product Version都是当前的Windows的Version,Kernel32.dll会随着当前的Windows的版本变化而变化。
    Show Me the Code:

HMODULE hKernel32 = GetModuleHandleA("KERNEL32.DLL");
char kernel32Path[256] = {0};
GetModuleFileNameA(hKernel32, kernel32Path, 256);

DWORD               dwSize              = 0;
BYTE                *pVersionInfo       = NULL;
VS_FIXEDFILEINFO    *pFileInfo          = NULL;
UINT                pLenFileInfo        = 0;


/*getting the file version info size */
dwSize = GetFileVersionInfoSizeA(kernel32Path, NULL);
if ( dwSize == 0 ) {
    cout << "Error in GetFileVersionInfoSize: " << GetLastError() << endl;
    return 1;
}

pVersionInfo = new BYTE[dwSize]; /*allocation of space for the verison size */

if (!GetFileVersionInfoA(kernel32Path, 0, dwSize, pVersionInfo)) { 
    /*entering all info data to pbVersionInfo*/
    cout << "Error in GetFileVersionInfo: %d" << GetLastError() << endl;
    delete[] pVersionInfo;
    return 1;
}

if (!VerQueryValueA(pVersionInfo, "\\", (LPVOID*) &pFileInfo, &pLenFileInfo)) {
    cout << "Error in VerQueryValue: %d" << GetLastError() << endl;
    delete[] pVersionInfo;
    return 1;
}

int major  = (pFileInfo->dwFileVersionMS >> 16) & 0xffff ;
int minor  = (pFileInfo->dwFileVersionMS)       & 0xffff;
int hotfix = (pFileInfo->dwFileVersionLS >> 16) & 0xffff;
int other  = (pFileInfo->dwFileVersionLS)       & 0xffff; 

delete[] pVersionInfo;

cout << "OS Version: " << major << "." << minor << "." << hotfix << "." << other << endl;

你可能感兴趣的:(获取Windows 10版本信息)