原文:https://blog.csdn.net/justFWD/article/details/44856277

内容整理如下,点击跳至指定内容:

  1. manifest文件加上compatibility节点

  2. 通过系统文件来读取

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

微软在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 = {  };

verInfo.dwOSVersionInfoSize = sizeof( verInfo );

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

if (RtlGetVersion !=  && RtlGetVersion( (PRTL_OSVERSIONINFOW)&verInfo ) == )

{

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 ),  );

}

VERSIONHELPERAPI

IsWindowsXPSP1OrGreater()

{

return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WINXP ), LOBYTE( _WIN32_WINNT_WINXP ),  );

}

VERSIONHELPERAPI

IsWindowsXPSP2OrGreater()

{

return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WINXP ), LOBYTE( _WIN32_WINNT_WINXP ),  );

}

VERSIONHELPERAPI

IsWindowsXPSP3OrGreater()

{

return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WINXP ), LOBYTE( _WIN32_WINNT_WINXP ),  );

}

VERSIONHELPERAPI

IsWindowsVistaOrGreater()

{

return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_VISTA ), LOBYTE( _WIN32_WINNT_VISTA ),  );

}

VERSIONHELPERAPI

IsWindowsVistaSP1OrGreater()

{

return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_VISTA ), LOBYTE( _WIN32_WINNT_VISTA ),  );

}

VERSIONHELPERAPI

IsWindowsVistaSP2OrGreater()

{

return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_VISTA ), LOBYTE( _WIN32_WINNT_VISTA ),  );

}

VERSIONHELPERAPI

IsWindows7OrGreater()

{

return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WIN7 ), LOBYTE( _WIN32_WINNT_WIN7 ),  );

}

VERSIONHELPERAPI

IsWindows7SP1OrGreater()

{

return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WIN7 ), LOBYTE( _WIN32_WINNT_WIN7 ),  );

}

VERSIONHELPERAPI

IsWindows8OrGreater()

{

return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WIN8 ), LOBYTE( _WIN32_WINNT_WIN8 ),  );

}

VERSIONHELPERAPI

IsWindows8Point1OrGreater()

{

return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WINBLUE ), LOBYTE( _WIN32_WINNT_WINBLUE ),  );

}

VERSIONHELPERAPI

IsWindows10OrGreater()

{

return IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WIN10 ), LOBYTE( _WIN32_WINNT_WIN10 ),  );

}

VERSIONHELPERAPI

IsWindowsServer()

{

OSVERSIONINFOEXW osvi = { sizeof( osvi ), , , , , {  }, , , , VER_NT_WORKSTATION };

DWORDLONG const dwlConditionMask = VerSetConditionMask( , 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_

获取windows版本号的更多相关文章

  1. C++通用WMI接口实现获取Windows操作系统内核版本号

    作为一名Windows开发者,能熟练掌握WMI技术,在开发Windows应用程序的时候往往能够事半功倍.今天来给大家分享一个使用WMI来获取Windows操作系统内核版本号的例子. 首先我们打开WMI ...

  2. 获取windows可执行文件的version信息(版本号)

    之前在msdn上Version Information看到文件版本信息的介绍,看着整体比较复杂,就一直没做.现在需要获取ocx文件的版本号,所以查找了下相关资料,比较有用的就是VS_FIXEDFILE ...

  3. C#:通过Visual Studio项目预生成命令获取SVN版本号

    之前有一个winfrom项目,想要通过获取SVN版本号作为程序的内部编译版本号.网上也有各种方法,但没有一篇行得通的方法.于是我经过一系列研究,得出了一些经验,特总结成一篇博客. 方法一:通过SVN命 ...

  4. C# 应用程序单例(禁止多开) 获取.net版本号 以及 管理员权限

    Mutex不仅提供跨线程的服务,还提供跨进程的服务.当在构造函数中为Mutex指定名称时,则会创建一个命名了的Mutex.其他线程创建Mutex时,如果指定的名称相同,则返回同一个互斥体,不论该线程位 ...

  5. 获取windows版本信息的做法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 个人不建议用 GetVersion 或GetVersionEx 之类的 API 来获取系统版本号.注意微软也说过,这个 ...

  6. python 镜像仓库获取最新版本号

    #/bin/python# -*- coding: utf-8 -*-import requestsfrom urllib import parsefrom requests.auth import ...

  7. 获取指定版本号svn

    代码需求获取 svn update  svnworkpath --username xxx --password xxx -r r464 r464 为指定版本号 可以获取指定版本号的代码 也 也可以在 ...

  8. 通过PowerShell获取Windows系统密码Hash

    当你拿到了系统控制权之后如何才能更长的时间内控制已经拿到这台机器呢?作为白帽子,已经在对手防线上撕开一个口子,如果你需要进一步扩大战果,你首先需要做的就是潜伏下来,收集更多的信息便于你判断,便于有更大 ...

  9. C#中获取程序集版本号的方法

    我的方法: string version = Assembly.GetExecutingAssembly().GetName().Version.ToString();   方法一: public v ...

随机推荐

  1. Activity并行网关和排他网关

    说一说activiti中的排他网关和并行网关 activiti工作流中我们经常用到的网关有两种: 1. Exclusive Gateway 排他网关 排他网关.png 排他网关(也叫异或(XOR)网关 ...

  2. 小程序-demo:小程序示例-page/component2

    ylbtech-小程序-demo:小程序示例-page/component2 以下将展示小程序官方组件能力,组件样式仅供参考,开发者可根据自身需求自定义组件样式,具体属性参数详见小程序开发文档. 1. ...

  3. WebUploader上传大文件时,上传出错问题

    上传普通文件没有问题,当文件达到一定大小的时候,上传错误,返回结果是404,我可以肯定的是路径是没有问题的.因为上传小文件等都是可以的. 然后使用webuploader的uploaderror监控错误 ...

  4. 06_传智播客iOS视频教程_源文件后缀名和main函数

    OC与C语言的不同. 把OC程序运行起来,CPU只会找main函数.并且只会执行main函数当中的代码.当main函数的代码执行完毕之后这个程序就自动结束掉了. main函数的参数是可以让我们在运行程 ...

  5. Tomcat cluster and session

    Cluster and session session consistency (1) session sticky source_ip: nginx: ip_hash haproxy: source ...

  6. The Power of Android Action Bars(转载)

    转自:http://www.informit.com/articles/article.aspx?p=1743642

  7. java面试(上)

    http://blog.csdn.net/jackfrued/article/details/44921941 1.面向对象的特征有哪些方面? 答:面向对象的特征主要有以下几个方面: - 抽象:抽象是 ...

  8. bzoj 3566: [SHOI2014]概率充电器【树形概率dp】

    设g[u]为这个点被儿子和自己充上电的概率,f[u]为被儿子.父亲和自己充上电的概率 然后根据贝叶斯公式(好像是叫这个),1.P(A+B)=P(A)+P(B)-P(A)*P(B),2.P(A)=(P( ...

  9. Luogu P1083 借教室【二分答案/差分】By cellur925

    题目描述 Description 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要 向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海 ...

  10. Ubuntu 18 开机后直接进入命令行界面,没法进入桌面

    应该是之前不知道干啥,删了gnome的一个东西,导致没法正常进入 暴力解决,直接重装桌面环境 sudo apt install ubuntu-desktop