您的位置:首页 > 其它

win10 系统版本号获取的三种方法

2015-04-03 15:52 316 查看
微软在windows 10的版本号获取上留下一个坑,如果用GetVersionEx获取版本号,则获取到的是6.2.9200

官方有如下说明

[GetVersionEx may
be altered or unavailable for releases after Windows 8.1. Instead, use the Version
Helper APIs]

也就是8.1开始就不正常了,那么如何正常判断版本号呢,下面列举一下可用的三个方法吧

1.manifest文件加上compatibility节点

<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
</application>
</compatibility>

但是这种方法局限性比较大,如果只是开发静态库什么的,就不可行

2.通过系统文件来读取



这是win10 kernel32.dll文件的属性信息,看到没有,这里有版本信息
可以通过GetFileVersionInfo 来获取,具体实现就不讲了

3.使用微软推荐的Version
Helper APIs来获取

函数是这个样子的:
IsWindows10OrGreater()


但是Requirements是这样的:

Minimum supported client
Windows 10 Technical Preview [desktop apps only]
Minimum supported server
Windows Server Technical Preview [desktop apps only]
Header
VersionHelpers.h (include Windows.h)
Library
Kernel32.lib;Ntdll.lib
DLL
Kernel32.dll;Ntdll.dll
需要windows 10以后才可用,老版本的系统怎么用呢

是不是只有win10下的kernel32.dll才导出了这个函数呢,是不是需要动态获取这个函数来判断?
用IDA看了一下win10 kernel32.dll的导出函数,没看到有这个函数,猜测应该是由头文件来实现的,于是找来一份VersionHelpers.h

真相大白,其实就是调用ntdll里的RtlGetVersion函数来实现的。我们只需要拷贝一份这个头文件,直接调用相应的函数就可以了
贴一下这个头文件吧

/******************************************************************
*                                                                 *
*  VersionHelpers.h -- This module defines helper functions to    *
*                      promote version check with proper          *
*                      comparisons.                               *
*                                                                 *
*  Copyright (c) Microsoft Corp.  All rights reserved.            *
*                                                                 *
******************************************************************/
#ifndef _versionhelpers_H_INCLUDED_
#define _versionhelpers_H_INCLUDED_

#ifndef ___XP_BUILD
#define WINAPI_PARTITION_DESKTOP   (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
#define WINAPI_FAMILY WINAPI_FAMILY_DESKTOP_APP
#define WINAPI_FAMILY_PARTITION(Partitions)     (Partitions)

#define _WIN32_WINNT_NT4                    0x0400
#define _WIN32_WINNT_WIN2K                  0x0500
#define _WIN32_WINNT_WINXP                  0x0501
#define _WIN32_WINNT_WS03                   0x0502
#define _WIN32_WINNT_WIN6                   0x0600
#define _WIN32_WINNT_VISTA                  0x0600
#define _WIN32_WINNT_WS08                   0x0600
#define _WIN32_WINNT_LONGHORN               0x0600
#define _WIN32_WINNT_WIN7                   0x0601
#define _WIN32_WINNT_WIN8                   0x0602
#endif

#ifdef _MSC_VER
#pragma once
#endif  // _MSC_VER

#pragma region Application Family

#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)

#include <specstrings.h>    // for _In_, etc.

#if !defined(__midl) && !defined(SORTPP_PASS)

#if (NTDDI_VERSION >= NTDDI_WINXP)

#ifdef __cplusplus

#define VERSIONHELPERAPI inline bool

#else  // __cplusplus

#define VERSIONHELPERAPI FORCEINLINE BOOL

#endif // __cplusplus

#define _WIN32_WINNT_WINBLUE                0x0603
#define _WIN32_WINNT_WIN10                  0x0A00

typedef NTSTATUS( NTAPI* fnRtlGetVersion )(PRTL_OSVERSIONINFOW lpVersionInformation);

VERSIONHELPERAPI
IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
{
/*OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 };
DWORDLONG        const dwlConditionMask = VerSetConditionMask(
VerSetConditionMask(
VerSetConditionMask(
0, VER_MAJORVERSION, VER_GREATER_EQUAL),
VER_MINORVERSION, VER_GREATER_EQUAL),
VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
osvi.dwMajorVersion = wMajorVersion;
osvi.dwMinorVersion = wMinorVersion;
osvi.wServicePackMajor = wServicePackMajor;
return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;*/

RTL_OSVERSIONINFOEXW verInfo = { 0 };
verInfo.dwOSVersionInfoSize = sizeof( verInfo );

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

if (RtlGetVersion != 0 && RtlGetVersion( (PRTL_OSVERSIONINFOW)&verInfo ) == 0)
{
if (verInfo.dwMajorVersion > wMajorVersion)
return true;
else if (verInfo.dwMajorVersion < wMajorVersion)
return false;

if (verInfo.dwMinorVersion > wMinorVersion)
return true;
else if (verInfo.dwMinorVersion < wMinorVersion)
return false;

if (verInfo.wServicePackMajor >= wServicePackMajor)
return true;
}

return false;
}

VERSIONHELPERAPI
IsWindowsXPOrGreater()
{
return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WINXP ), LOBYTE( _WIN32_WINNT_WINXP ), 0 );
}

VERSIONHELPERAPI
IsWindowsXPSP1OrGreater()
{
return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WINXP ), LOBYTE( _WIN32_WINNT_WINXP ), 1 );
}

VERSIONHELPERAPI
IsWindowsXPSP2OrGreater()
{
return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WINXP ), LOBYTE( _WIN32_WINNT_WINXP ), 2 );
}

VERSIONHELPERAPI
IsWindowsXPSP3OrGreater()
{
return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WINXP ), LOBYTE( _WIN32_WINNT_WINXP ), 3 );
}

VERSIONHELPERAPI
IsWindowsVistaOrGreater()
{
return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_VISTA ), LOBYTE( _WIN32_WINNT_VISTA ), 0 );
}

VERSIONHELPERAPI
IsWindowsVistaSP1OrGreater()
{
return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_VISTA ), LOBYTE( _WIN32_WINNT_VISTA ), 1 );
}

VERSIONHELPERAPI
IsWindowsVistaSP2OrGreater()
{
return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_VISTA ), LOBYTE( _WIN32_WINNT_VISTA ), 2 );
}

VERSIONHELPERAPI
IsWindows7OrGreater()
{
return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WIN7 ), LOBYTE( _WIN32_WINNT_WIN7 ), 0 );
}

VERSIONHELPERAPI
IsWindows7SP1OrGreater()
{
return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WIN7 ), LOBYTE( _WIN32_WINNT_WIN7 ), 1 );
}

VERSIONHELPERAPI
IsWindows8OrGreater()
{
return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WIN8 ), LOBYTE( _WIN32_WINNT_WIN8 ), 0 );
}

VERSIONHELPERAPI
IsWindows8Point1OrGreater()
{
return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WINBLUE ), LOBYTE( _WIN32_WINNT_WINBLUE ), 0 );
}

VERSIONHELPERAPI
IsWindows10OrGreater()
{
return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WIN10 ), LOBYTE( _WIN32_WINNT_WIN10 ), 0 );
}

VERSIONHELPERAPI
IsWindowsServer()
{
OSVERSIONINFOEXW osvi = { sizeof( osvi ), 0, 0, 0, 0, { 0 }, 0, 0, 0, VER_NT_WORKSTATION };
DWORDLONG        const dwlConditionMask = VerSetConditionMask( 0, VER_PRODUCT_TYPE, VER_EQUAL );

return !VerifyVersionInfoW( &osvi, VER_PRODUCT_TYPE, dwlConditionMask );
}

#endif // NTDDI_VERSION

#endif // defined(__midl)

#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */

#pragma endregion

#endif // _VERSIONHELPERS_H_INCLUDED_
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: