原文: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. 连接mysql时报:message from server: "Host '192.168.76.89' is not allowed to connect to this MySQL server

    处理方案: 1.先用localhost方式连接到MySQL数据库,然后使用MySQL自带的数据库mysql; use mysql: 2.执行:select host from user where u ...

  2. 【JSOI 2008】 最大数

    [题目链接] 点击打开链接 [算法] 很明显,我们可以用线段树解决此题 只需维护区间最值就可以了 [代码] #include<bits/stdc++.h> using namespace ...

  3. lua 与 c 的相互调用

    Lua是一个嵌入式的语言,意味着Lua不仅可以是一个独立运行的程序包也可以是一个用来嵌入其他应用的程序库. Lua可以作为程序库用来扩展应用的功能,也就是Lua可以作为扩展性语言的原因所在.同时,Lu ...

  4. bzoj4720

    期望dp n久以前做过,再做一遍 你只能决定决策,不能决定结果,这是这道题的关键,因为我们换了教室不一定成功,所以我们应该这样设dp状态,dp[i][j][k],第i天,换j次,换没换,转移: dp[ ...

  5. 设计模式-Template Method Pattern

    将generic部份放在abstract base class中的实现的方法中,而将和具体context相关的部份作为abstract base class的虚方法,由derivatives去实现. ...

  6. 关于python安装lxml插件的问题

    文章只是介绍自己安装时从安装不上到安装后报错,再到安装成功的心路历程,并不代表广大欧皇也会会出现同类型的问题,也不是总结和汇总各种出问题的原因. 直接进入正题,首先我这边是win环境,电脑上装的是py ...

  7. 【SQL】从待选项中随机选一个

    由于SQL Server没有数组类型,所以在面对“从若干待选项中选一个”这种需求时,往往要采取变通办法,比如弄个‘a|b|c’这样的字符串然后对字符串进行处理:又或者把待选项塞进一个临时表,然后把问题 ...

  8. linux 重名名、删除文件操作

    linux下重命名文件或文件夹的命令mv既可以重命名,又可以移动文件或文件夹. 例子:将目录A重命名为B mv A B 例子:将/a目录移动到/b下,并重命名为c mv /a /b/c 删除文件夹 r ...

  9. Windows下安装Ubuntu16.04双系统

    ROS需要在Ubuntu系统上开发,虚拟机跑Ubuntu开发ROS容易出现各种各样的问题,所以需要安装Ubuntu16.04双系统.笔者也是一步步按着网上的帖子来,由于网上的教程都不是最新的而且有的也 ...

  10. bzoj1233 [Usaco2009Open]干草堆tower 【单调队列dp】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1233 单调队列优化的第一题,搞了好久啊,跟一开始入手斜率优化时感觉差不多... 这一题想通了 ...