热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

GetVersionEx如何区分win8和win8.1

获取的win8和win8.1都是6.2那么该如何区分而且wProductTypeVER_NT_WORKSTATION
获取的win8和win8.1都是6.2 那么该如何区分 而且wProductType==VER_NT_WORKSTATION

21 个解决方案

#1


8.1 的版本号应该是 6.3 吧,不知道你是怎么获取的,难道是兼容模式?
http://msdn.microsoft.com/en-us/library/ms724832.aspx
个人不建议用 GetVersion 或 GetVersionEx 之类的 API 来获取系统版本号。注意微软也说过,这个结果会受到兼容模式的影响,即如果程序设置兼容模式为 XP 那么拿到的也可能使 5.1 的。所以要准确的获取版本号,我建议直接获取 kernel32.dll 的主版本号,这个是和系统的版本号是一样的。

#2


DWORD GetKernelMajorVerion(void)
{
    DWORD dwVersion = MAKELONG(0, 0);
    WCHAR szDLLName[MAX_PATH] = { 0 };
    HRESULT hr = SHGetFolderPathW(NULL, CSIDL_SYSTEM, NULL, SHGFP_TYPE_CURRENT, szDLLName);
    if (SUCCEEDED(hr) && PathAppendW(szDLLName, L"kernel32.dll")) {
        DWORD dwVerInfoSize = GetFileVersionInfoSizeW(szDLLName, NULL);
        if (dwVerInfoSize > 0) {
            LPVOID pvVerInfoData = (LPVOID)new BYTE[dwVerInfoSize];
            if (GetFileVersionInfoW(szDLLName, 0, dwVerInfoSize, pvVerInfoData)) {
                UINT ulLength = 0;
                VS_FIXEDFILEINFO *pvffi = NULL;
                if (VerQueryValueW(pvVerInfoData, L"\\", (LPVOID *)&pvffi, &ulLength)) {
                    dwVersion = pvffi->dwFileVersionMS;
                }
            }
            delete[] pvVerInfoData;
        }
    }
    return dwVersion;
}

#3


现在应该用新API取代旧的GetVersion/ and GetVersionEx了
IsWindows8Point1OrGreater()
http://msdn.microsoft.com/en-us/library/windows/desktop/dn424972%28v=vs.85%29.aspx

#4


引用 3 楼 nokia007 的回复:
现在应该用新API取代旧的GetVersion/ and GetVersionEx了
IsWindows8Point1OrGreater()
http://msdn.microsoft.com/en-us/library/windows/desktop/dn424972%28v=vs.85%29.aspx

这个并非系统 API,而是由头文件 versionhelpers.h 提供的,其中有具体的实现,它是通过 VerifyVersionInfo 函数实现的,这个函数会受到兼容性设置的影响。系统中所有获取系统版本号的函数都会受到兼容性设置的影响,唯有获取 kernel32.dll 的版本号是最保险的。

#5


回楼上,我试了一下在Win8.1下设置为Win7兼容模式,获取的还是8.1.应该没有问题吧。

#6


对于一个 未加特殊处理的应用程序用GetVersionEx获取win8和win8.1系统版本, 一律都是6.2

这是微软的兼容性考虑

如果你的程序是专门为Win8.1准备的,那么可以 主动说明,这时候获得的版本是6.2和6.3

Win8.1的版本实际上是6.3

如何主动说明呢?加manifest,核心内容如下:




  
    
      
    
 
  

#7


引用 6 楼 my3439955 的回复:
对于一个 未加特殊处理的应用程序用GetVersionEx获取win8和win8.1系统版本, 一律都是6.2

这是微软的兼容性考虑

如果你的程序是专门为Win8.1准备的,那么可以 主动说明,这时候获得的版本是6.2和6.3

Win8.1的版本实际上是6.3

如何主动说明呢?加manifest,核心内容如下:




  
    
      
    
 
  


传个代码说明一下  http://download.csdn.net/detail/my3439955/8267571

#8


还真没了解过,没有真正测试过在 8.1 上获取的版本号也是 6.1。
这是我现在常用的一个 manifest 配置,让 C 风格程序使用主题:


    
        
            
        

    

    
        
            
                
            

        

    
    
        
            
             
            
            
            
            
            
            
        

    

#9


这个没试过,帮忙顶一下!

#10


引用 8 楼 SXJIAKE 的回复:
还真没了解过,没有真正测试过在 8.1 上获取的版本号也是 6.1。
这是我现在常用的一个 manifest 配置,让 C 风格程序使用主题:


    
        
            
        

    

    
        
            
                
            

        

    
    
        
            
             
            
            
            
            
            
            
        

    



6.1是win7,win8和win8.1不会获取到6.1,至少也是6.2

#11


可以用ntdll中的RtlGetNtVersionNumbers
typedef void (__stdcall*NTPROC)(DWORD*,DWORD*,DWORD*);
void GetWinVer()
{
HINSTANCE hinst = LoadLibrary("ntdll.dll");
DWORD dwMajor,dwMinor,dwBuildNumber;
NTPROC proc = (NTPROC)GetProcAddress(hinst,"RtlGetNtVersionNumbers");
proc(&dwMajor,&dwMinor,&dwBuildNumber);
dwBuildNumber&=0xffff;
}

这是一个undocumented API

#12


填充以下数据

typedef struct _OSVERSIONINFO{ 
    DWORD dwOSVersionInfoSize; 
    DWORD dwMajorVersion; 
    DWORD dwMinorVersion; 
    DWORD dwBuildNumber; 
    DWORD dwPlatformId; 
    TCHAR szCSDVersion[ 128 ]; 
} OSVERSIONINFO

#13


引用 2 楼 SXJIAKE 的回复:
DWORD GetKernelMajorVerion(void)
{
    DWORD dwVersion = MAKELONG(0, 0);
    WCHAR szDLLName[MAX_PATH] = { 0 };
    HRESULT hr = SHGetFolderPathW(NULL, CSIDL_SYSTEM, NULL, SHGFP_TYPE_CURRENT, szDLLName);
    if (SUCCEEDED(hr) && PathAppendW(szDLLName, L"kernel32.dll")) {
        DWORD dwVerInfoSize = GetFileVersionInfoSizeW(szDLLName, NULL);
        if (dwVerInfoSize > 0) {
            LPVOID pvVerInfoData = (LPVOID)new BYTE[dwVerInfoSize];
            if (GetFileVersionInfoW(szDLLName, 0, dwVerInfoSize, pvVerInfoData)) {
                UINT ulLength = 0;
                VS_FIXEDFILEINFO *pvffi = NULL;
                if (VerQueryValueW(pvVerInfoData, L"\\", (LPVOID *)&pvffi, &ulLength)) {
                    dwVersion = pvffi->dwFileVersionMS;
                }
            }
            delete[] pvVerInfoData;
        }
    }
    return dwVersion;
}

只能获得主版本号吗?如果具体区分是不还应该增加获得副信息号功能?

#14


引用 13 楼 CIPORE 的回复:
只能获得主版本号吗?如果具体区分是不还应该增加获得副信息号功能?

目前覺得,取得 kernel32.dll 得到系統的準確主版本號,配合 GetSystemInfo (GetNativeSysteminfo) 和 GetVersionEx 還是可以用的,傳一個 OSVERSIONINFOEX 結構體,可以通過其中除了系統版本號、Service Pack 版本等這些容易收到兼容性影響而得到錯誤結果之外的其他值來確定大致版本號。

排除 SP,如何精確判斷系統,可參考此頁:
https://msdn.microsoft.com/en-us/library/ms724833.aspx
其中 Remarks 段有具體說明。

如果要在兼容性模式下獲取精確 Service Pack 可能就不好辦了,畢竟兼容性裡面有 XP SP2 和 XP SP3,因此 OSVERSIONINFOEX 的 szCSDVersion、wServicePackMajor、wServicePackMinor 的結果也可能也不準確。但是畢竟兼容性設置再強悍也不可能把個人系統“兼容”為服務器系統吧,也不會把32位“兼容”為64位吧。比如 OSVERSIONINFOEX.wProductType 這個參數,應該是不會受兼容性影響。

#15


分享一個我自己用於比較精確的系統版本判斷 C 代碼:
http://pan.baidu.com/s/1eQkykuQ
之所以叫比較精確,因為 Service Pack 可以通過兼容模式來偽造,因此只獲取系統名稱和位數。

#16


引用 13 楼 CIPORE 的回复:
只能获得主版本号吗?如果具体区分是不还应该增加获得副信息号功能?

忘了說明了,dwFileVersionMS 得到的其實是類似 6.2、6.3 這樣的。你具體看我的例子吧。

#17


Win8.1的确是6.3,通过DLL的方法还是靠谱的。

#18


引用 15 楼 SXJIAKE 的回复:
分享一個我自己用於比較精確的系統版本判斷 C 代碼:
http://pan.baidu.com/s/1eQkykuQ
之所以叫比較精確,因為 Service Pack 可以通過兼容模式來偽造,因此只獲取系統名稱和位數。

这位大神,我现在也在想要这方面的资料,你提供的链接已经没有了,能在提供一个吗。

#19


引用 18 楼 yayexing 的回复:
Quote: 引用 15 楼 SXJIAKE 的回复:

分享一個我自己用於比較精確的系統版本判斷 C 代碼:
http://pan.baidu.com/s/1eQkykuQ
之所以叫比較精確,因為 Service Pack 可以通過兼容模式來偽造,因此只獲取系統名稱和位數。

这位大神,我现在也在想要这方面的资料,你提供的链接已经没有了,能在提供一个吗。

#include 
// 所需头和库
#include 
#pragma comment(lib, "netapi32.lib")
// 获取版本号
WKSTA_INFO_100 *wkstaInfo = NULL;
NET_API_STATUS netStatus = NetWkstaGetInfo(NULL, 100, (LPBYTE *)&wkstaInfo);
if (netStatus == NERR_Success) {
    DWORD dwMajVer = wkstaInfo->wki100_ver_major;
    DWORD dwMinVer = wkstaInfo->wki100_ver_minor;
    DWORD dwVersion = (DWORD)MAKELONG(dwMinVer, dwMajVer);
    netStatus = NetApiBufferFree(wkstaInfo);
}
此方法可以获取到准确的版本号,不依赖于 manifest 文件,也不受兼容性的影响。

#20


通过以下结构体返回你需要的各项数据

The OSVERSIONINFOEX structure contains operating system version information. The information includes major and minor version numbers, a build number, a platform identifier, and information about the latest Service Pack installed on the system. This structure is used with the GetVersionEx function. OSVERSIONINFOEX is an extended version of the OSVERSIONINFO structure. 

typedef struct _OSVERSIONINFOEXA {
    DWORD dwOSVersionInfoSize;
    DWORD dwMajorVersion;
    DWORD dwMinorVersion;
    DWORD dwBuildNumber;
    DWORD dwPlatformId;
    TCHAR szCSDVersion[ 128 ];
    WORD wServicePackMajor;
    WORD wServicePackMinor;
    WORD wReserved[2];
} OSVERSIONINFOEXA, *POSVERSIONINFOEXA, *LPOSVERSIONINFOEXA;
 
Members
dwOSVersionInfoSize 
Specifies the size, in bytes, of this data structure. Set this member to sizeof(OSVERSIONINFOEX) before calling the GetVersionEx function. 
dwMajorVersion 
Identifies the major version number of the operating system. For example, for Windows NT version 5.0, the major version number is 5. 
dwMinorVersion 
Identifies the minor version number of the operating system. For example, for Windows NT version 5.0, the minor version number is 0. 
dwBuildNumber 
Identifies the build number of the operating system. 
dwPlatformId 
Identifies the operating system platform. This member can be one of the following values. Value Platform 
VER_PLATFORM_WIN32s Win32s on Windows 3.1.  
VER_PLATFORM_WIN32_WINDOWS Win32 on Windows 95 or Windows 98.  
VER_PLATFORM_WIN32_NT Win32 on Windows NT. 


szCSDVersion 
Contains a null-terminated string, such as "Service Pack 3", that indicates the latest Service Pack installed on the system. If no Service Pack has been installed, the string is empty. 
wServicePackMajor 
Identifies the major version number of the latest Service Pack installed on the system. If no Service Pack has been installed, the value is zero. 
wServicePackMinor 
Identifies the minor version number of the latest Service Pack installed on the system. If no Service Pack has been installed, the value is zero. 
wReserved 
Reserved for future use. 
QuickInfo

#21


引用 19 楼 SXJIAKE 的回复:
Quote: 引用 18 楼 yayexing 的回复:

Quote: 引用 15 楼 SXJIAKE 的回复:

分享一個我自己用於比較精確的系統版本判斷 C 代碼:
http://pan.baidu.com/s/1eQkykuQ
之所以叫比較精確,因為 Service Pack 可以通過兼容模式來偽造,因此只獲取系統名稱和位數。

这位大神,我现在也在想要这方面的资料,你提供的链接已经没有了,能在提供一个吗。

#include 
// 所需头和库
#include 
#pragma comment(lib, "netapi32.lib")
// 获取版本号
WKSTA_INFO_100 *wkstaInfo = NULL;
NET_API_STATUS netStatus = NetWkstaGetInfo(NULL, 100, (LPBYTE *)&wkstaInfo);
if (netStatus == NERR_Success) {
    DWORD dwMajVer = wkstaInfo->wki100_ver_major;
    DWORD dwMinVer = wkstaInfo->wki100_ver_minor;
    DWORD dwVersion = (DWORD)MAKELONG(dwMinVer, dwMajVer);
    netStatus = NetApiBufferFree(wkstaInfo);
}
此方法可以获取到准确的版本号,不依赖于 manifest 文件,也不受兼容性的影响。

小弟受教了,此方法确实可以获取到版本号和副版本号,我前面用您之前提供的获取kernel32.dll的版本信息,在win10下面取到的大版本号也是6.2,后面dll的编译号却是不受影响,唉,好久没在csdn里面取到这么有分享精神的大神了,太感谢了。

推荐阅读
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了游标的使用方法,并以一个水果供应商数据库为例进行了说明。首先创建了一个名为fruits的表,包含了水果的id、供应商id、名称和价格等字段。然后使用游标查询了水果的名称和价格,并将结果输出。最后对游标进行了关闭操作。通过本文可以了解到游标在数据库操作中的应用。 ... [详细]
  • PHPMailer邮件类邮件发送功能的使用教学及注意事项
    本文介绍了使用国外开源码PHPMailer邮件类实现邮件发送功能的简单教学,同时提供了一些注意事项。文章涵盖了字符集设置、发送HTML格式邮件、群发邮件以及避免类的重定义等方面的内容。此外,还提供了一些与PHP相关的资源和服务,如传奇手游游戏源码下载、vscode字体调整、数据恢复、Ubuntu实验环境搭建、北京爬虫市场、进阶PHP和SEO人员需注意的内容。 ... [详细]
  • 基于dlib的人脸68特征点提取(眨眼张嘴检测)python版本
    文章目录引言开发环境和库流程设计张嘴和闭眼的检测引言(1)利用Dlib官方训练好的模型“shape_predictor_68_face_landmarks.dat”进行68个点标定 ... [详细]
  • 如何查询zone下的表的信息
    本文介绍了如何通过TcaplusDB知识库查询zone下的表的信息。包括请求地址、GET请求参数说明、返回参数说明等内容。通过curl方法发起请求,并提供了请求示例。 ... [详细]
  • 本文介绍了OpenStack的逻辑概念以及其构成简介,包括了软件开源项目、基础设施资源管理平台、三大核心组件等内容。同时还介绍了Horizon(UI模块)等相关信息。 ... [详细]
author-avatar
dfdzgf_542
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有