原文: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. Linux设备模型 (1)

    随着计算机的周边外设越来越丰富,设备管理已经成为现代操作系统的一项重要任务,这对于Linux来说也是同样的情况.每次Linux内核新版本的发布,都会伴随着一批设备驱动进入内核.在Linux内核里,驱动 ...

  2. caj转pdf——包含下载链接

    很多人在知网上下载论文后,想转换成PDF格式,本片一站式教学,包含下载链接. 需要工具 1 caj格式的文件,即要转换的文件. 2 cajviewer,可以在知网的官网上面下载,下载地址参考这里. 3 ...

  3. [App Store Connect帮助]七、在 App Store 上发行(3.3)提交至“App 审核”:解决 App 拒绝问题

    如果“App 审核”或“Beta 版 App 审核”拒绝了您的 App,您可以与 Apple 沟通并在解决方案中心中解决问题. 来自 Apple 的通讯信息包含有关 App 拒绝的信息,其中包括该 A ...

  4. CentOS中设置Windows共享文件夹

    在CentOS中设置Samba可实现和Windows共享文件夹.常见的需求:1)用户能够在Windows机器上通过共享文件夹访问远程Linux服务器上自己的主目录:2)用户能够在Windows机器上访 ...

  5. 网站SEO优化如何让百度搜索引擎绝的你的网站更有抓取和收录价值呢?_孙森SEO

    今天孙森SEO为大家唠唠网站到底该如何优化才会让百度搜索引擎绝的你的网站更有抓取和收录价值呢? 第一方面:网站创造高品质的内容,可以为用户提供独特的价值. 1.百度作为搜索引擎,网站内容必须满足 搜索 ...

  6. 【牛客-14602】xinjun与阴阳师(01背包)

    xinjun与阴阳师 题目描述 xinjun是各类手游的狂热粉丝,因随手一氪.一氪上千而威震工大,现在他迷上了阴阳师.xinjun玩手游有一个习惯,就是经过层层计算制定出一套方案来使操作利益最大化(因 ...

  7. Kerberos原理和基础小结

    此篇文章仅做Kerberos的基本原理和基本使用做说明,本人对Kerberos了解有限,也是通过大量英文文档中翻译过来, 加上自己对Kerberos的理解所写,本人英文太菜,看文档看的头昏眼花若有写的 ...

  8. Tarjan UVALive 6511 Term Project

    题目传送门 /* 题意:第i个人选择第a[i]个人,问组成强联通分量(自己连自己也算)外还有多少零散的人 有向图强联通分量-Tarjan算法:在模板上加一个num数组,记录每个连通分量的点数,若超过1 ...

  9. Java标识符的习惯命名规范

    1 常量标识符:全部用大写字母和下划线表示.如SALES_MAX 2 类名或接口名:标识符用大写字母开头.如CreditCard 3 变量名和方法名:以小写字母开头,单词之间不要有分隔符,第二 及后面 ...

  10. C#---数据库访问通用类、Access数据库操作类、mysql类 .[转]

    原文链接 //C# 数据库访问通用类 (ADO.NET)using System;using System.Collections.Generic;using System.Text;using Sy ...