0

获取Windows版本号

发表者:wenzhou1219分类:接口2016-01-24 17:34:58 阅读[1252]

在Win8以前获取Windows版本号,一般都使用GetVersionEx,如winXP(5.1),Win7(6.1),Win8(6.2)。但是到了Win8.1开始就不行了,这时候使用GetVersionEx会发现Win8.1和Win10开始都是6.2,这怎么能行。


为了解决这个问题,首先我们需要知道版本信息是GetVersionEx从进程PEB中拿取的,用工具查看会发现PEB中的信息是正确的,但是GetVersionEx却不正确,这是微软取数据机制发生了变化。在这种情况下,我们可以换用RtlGetVersion,这是一个内核函数,会发现他的结果还是对的。另外如果从ntdll.dll中导出RtlGetVersion失败的话,我们还可以通过判断系统文件如kernel32.dll的版本来判断当前操作系统版本。


总结来说,获取Windows版本号方法如下:

1.Windows2000~Win 7 GetVersionEx

2.Win8*~ RtlGetVersion

3.GetFileVersionInfo获取kerne32.dll的版本进而判断系统版本


核心代码如下:

	//计算系统版本信息
	WIN_VER CalcWinVerInfo()
	{
		//获得系统主次版本号
		ULONG dwMajorVersion=0;
		ULONG dwMinorVersion=0;

		//Win8以前可使用GetVersionEx,适用于Windows 2000~Windows 7
		OSVERSIONINFO osvi={0};
		osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

		GetVersionEx (&osvi);
		dwMajorVersion = osvi.dwMajorVersion;
		dwMinorVersion = osvi.dwMinorVersion;

		AtlTrace(L"GetVersionEx-%d-%d", dwMajorVersion, dwMinorVersion);

		//判断系统版本
		if (dwMajorVersion==5 && dwMinorVersion==0)
		{
			m_WinVer = WIN_VER_2000;
		}
		else if (dwMajorVersion==5 && dwMinorVersion==1)
		{
			m_WinVer = WIN_VER_XP;
		}
		else if (dwMajorVersion==5 && dwMinorVersion==2)
		{
			m_WinVer = WIN_VER_2003;
		}
		else if (dwMajorVersion==6 && dwMinorVersion==0)
		{
			m_WinVer = WIN_VER_VISTA;
		}
		else if (dwMajorVersion==6 && dwMinorVersion==1)
		{
			m_WinVer = WIN_VER_WIN7;
		}
		else 
		{
			//win8开始使用RtlGetVersion(适用于>=XP)
			RTL_OSVERSIONINFOW rtl_vi={0};
			rtl_vi.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW);
			pfnRtlGetVersion fnRtlGetVersion = NULL;

			fnRtlGetVersion = (pfnRtlGetVersion)GetProcAddress( GetModuleHandleW( L"ntdll.dll" ), "RtlGetVersion" );

			if (fnRtlGetVersion)
			{
				fnRtlGetVersion(&rtl_vi);
				dwMajorVersion = rtl_vi.dwMajorVersion;
				dwMinorVersion = rtl_vi.dwMinorVersion;

				AtlTrace(L"RtlGetVersion-%d-%d", dwMajorVersion, dwMinorVersion);

				if (dwMajorVersion==6 && dwMinorVersion==2)
				{
					m_WinVer = WIN_VER_WIN8;
				}
				else if (dwMajorVersion==6 && dwMinorVersion==3)
				{
					m_WinVer = WIN_VER_WIN81;
				}
				else if ((dwMajorVersion==10 && dwMinorVersion==0) ||
					     (dwMajorVersion==6 && dwMinorVersion==4))//Win10版本号可能为6.4或10.0
				{
					m_WinVer = WIN_VER_WIN10;
				}
			}
			else//RtlGetVersion不行的话该取kernel.dll版本
			{
				TCHAR szSystemDir[MAX_PATH]={0};

				//获得system32下kernel.dll文件路径
				GetSystemDirectory(szSystemDir, MAX_PATH);
				//ATLASSERT(szSystemDir!=NULL);
				PathCombine(szSystemDir, szSystemDir, _T("kernel32.dll"));

				//获得文件版本从而计算操作系统版本
				DWORD dwMajorVer = 0;
				DWORD dwMinorVer = 0;
				if (GetFileVersion(szSystemDir, dwMajorVer, dwMinorVer))
				{
					AtlTrace(L"GetFileVersion-%d-%d", dwMajorVer, dwMinorVer);

					if (dwMajorVer == MAKELONG(2,6))
					{
						m_WinVer = WIN_VER_WIN8;
					}
					else if (dwMajorVer == MAKELONG(3,6))
					{
						m_WinVer = WIN_VER_WIN81;
					}
					else if (dwMajorVer == MAKELONG(0,10) || 
						     dwMajorVer == MAKELONG(4,6))
					{
						m_WinVer = WIN_VER_WIN10;
					}
				}
			}
		}

		return m_WinVer;
	}

演示程序和CSystemInfo类的代码下载链接    访问密码 8150


名字:

个人主页地址:

E-mail:

评论列表