C++ Coder

HCP高性能计算架构,实现,编译器指令优化,算法优化, LLVM CLANG OpenCL CUDA OpenACC C++AMP OpenMP MPI

C++博客 首页 新随笔 联系 聚合 管理
  98 Posts :: 0 Stories :: 0 Comments :: 0 Trackbacks

GetVersion和GetVersionEx

出自:http://flyxxtt.blogbus.com/logs/42705986.html

Windows API 中有两个函数可以得到系统版本信息GetVersionGetVersionEx

      GetVersion这个函数曾经困扰了很多程序员,其本来设计的是在DWORD返回值中用低位的那个字表示MS-DOS的版本号,高位的那个字表示Windows版本号。对于每个字来说,高位字节代表主要版本号,低位字节代表次要版本号。可是因为编写此函数的程序员犯了一个错误,使得此函数返回的Windows版本号颠倒了(即把主要版本号放到了低位字节,而次要版本号放到了高位字节)。当发现此错误的时候已经有很多程序员在使用这个函数了,Microsoft只好将错就错,直接把原来的API文档给改了过来。

      为了解决GetVersion带来的问题,Microsoft后来开发了一个新的函数GetVersionEx,用它能够得到更详细的Windows系统的版本信息,下面我就写写GetVersionEx的使用方法。

 

函数原型:

 

BOOL GetVersionEx(POSVERSIONINFO pVersionInformation);

 

我们先来看看OSVERSIONINFOEX这个结构:

typedef struct {

DWORD dwOSVersionInfoSize;       
//在使用GetVersionEx之前要将此初始化为结构的大小

DWORD dwMajorVersion;               
//系统主版本号

DWORD dwMinorVersion;               
//系统次版本号

DWORD dwBuildNumber;               
//系统构建号

DWORD dwPlatformId;                  
//系统支持的平台(详见附1)

TCHAR szCSDVersion[
128];          //系统补丁包的名称

WORD wServicePackMajor;            
//系统补丁包的主版本

WORD wServicePackMinor;            
//系统补丁包的次版本

WORD wSuiteMask;                      
//标识系统上的程序组(详见附2)

BYTE wProductType;                    
//标识系统类型(详见附3)

BYTE wReserved;                         
//保留,未使用

}
 OSVERSIONINFOEX, *POSVERSIONINFOEX;

这个结构在Windows 2000后出现,老版本的OSVERSIONINFO结构没有wServicePackMajor、wServicePackMinor、wSuiteMask、wProductType和wReserved这几个成员。

 

接着在调用函数之前先初始化结构的大小:

OSVERSIONINFOEX os;
os.dwOSVersionInfoSize
=sizeof(os);

函数返回值为TRUE表示成功:

if(!GetVersionEx((OSVERSIONINFO *)&os))
{
      
return FALSE;
}

函数调用成功以后就可以通过OSVERSIONINFOEX来查看系统的版本信息了。

下面是一个通过系统版本来判断操作系统名称的例子:

CString getSystemName()

{

    SYSTEM_INFO info;                                   
//用SYSTEM_INFO结构判断64位AMD处理器
    GetSystemInfo(&info);                               //调用GetSystemInfo函数填充结构
    OSVERSIONINFOEX os;
    os.dwOSVersionInfoSize
=sizeof(OSVERSIONINFOEX); 
    
if(GetVersionEx((OSVERSIONINFO *)&os))                  
    
{
        CString vname;

        
//下面根据版本信息判断操作系统名称

        
switch(os.dwMajorVersion){                        //判断主版本号
            case 4:
                
switch(os.dwMinorVersion){                //判断次版本号
                    case 0:
                        
if(os.dwPlatformId==VER_PLATFORM_WIN32_NT)
                            vname
=_T("Microsoft Windows NT 4.0");                //1996年7月发布
                        else if(os.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
                            vname
=_T("Microsoft Windows 95");
                        
break;
                    
case 10:
                        vname
=_T("Microsoft Windows 98");
                        
break;
                    
case 90:
                        vname
=_T("Microsoft Windows Me");
                        
break;
                }

                
break;
            
case 5:
                
switch(os.dwMinorVersion){               //再比较dwMinorVersion的值
                    case 0:
                        vname
=_T("Microsoft Windows 2000");                    //1999年12月发布
                        break;
                    
case 1:
                        vname
=_T("Microsoft Windows XP");                    //2001年8月发布
                        break;
                    
case 2:
                        
if(os.wProductType==VER_NT_WORKSTATION && /

                           info.wProcessorArchitecture
==PROCESSOR_ARCHITECTURE_AMD64)

                            vname
=_T("Microsoft Windows XP Professional x64 Edition");
                        
else if(GetSystemMetrics(SM_SERVERR2)==0)
                            vname
=_T("Microsoft Windows Server 2003");        //2003年3月发布
                        else if(GetSystemMetrics(SM_SERVERR2)!=0)
                            vname
=_T("Microsoft Windows Server 2003 R2");
                        
break;
                }

                
break;
            
case 6:
                
switch(os.dwMinorVersion){
                    
case 0:
                        
if(os.wProductType==VER_NT_WORKSTATION)
                            vname
=_T("Microsoft Windows Vista");
                        
else
                            vname
=_T("Microsoft Windows Server 2008");          //服务器版本
                        break;
                    
case 1:
                        
if(os.wProductType==VER_NT_WORKSTATION)
                            vname
=_T("Microsoft Windows 7");
                        
else
                            vname
=_T("Microsoft Windows Server 2008 R2");
                        
break;
                }

                
break;
            
default:
                vname
=_T("未知操作系统");
        }

        
return vname;
    }

    
else
        
return _T("");

}


以上只能判断操作系统的名称,那如何判断它是什么版本的呢(如Home版或Professional版)。

下面这个函数就返回具体的版本名称

CString getVersionMark()

{

    OSVERSIONINFOEX os;
    os.dwOSVersionInfoSize
=sizeof(OSVERSIONINFOEX);
    
if(GetVersionEx((OSVERSIONINFO *)&os)){
        CString vmark;

        
switch(os.dwMajorVersion){                //先判断操作系统版本
            case 5:
                
switch(os.dwMinorVersion){
                    
case 0:                  //Windows 2000
                        if(os.wSuiteMask==VER_SUITE_ENTERPRISE)
                            vmark
=_T("Advanced Server");
                        
break;
                    
case 1:                  //Windows XP
                        if(os.wSuiteMask==VER_SUITE_EMBEDDEDNT)
                            vmark
=_T("Embedded");
                        
else if(os.wSuiteMask==VER_SUITE_PERSONAL)
                            vmark
=_T("Home Edition");
                        
else
                            vmark
=_T("Professional");
                        
break;
                    
case 2:
                        
if(GetSystemMetrics(SM_SERVERR2)==0 && /

                        os.wSuiteMask
==VER_SUITE_BLADE)  //Windows Server 2003
                            vmark=_T("Web Edition");
                        
else if(GetSystemMetrics(SM_SERVERR2)==0 && /

                        os.wSuiteMask
==VER_SUITE_COMPUTE_SERVER)
                            vmark
=_T("Compute Cluster Edition");
                        
else if(GetSystemMetrics(SM_SERVERR2)==0 && /

                        os.wSuiteMask
==VER_SUITE_STORAGE_SERVER)
                            vmark
=_T("Storage Server");
                        
else if(GetSystemMetrics(SM_SERVERR2)==0 && /

                        os.wSuiteMask
==VER_SUITE_DATACENTER)
                            vmark
=_T("Datacenter Edition");
                        
else if(GetSystemMetrics(SM_SERVERR2)==0 && /

                        os.wSuiteMask
==VER_SUITE_ENTERPRISE)
                            vmark
=_T("Enterprise Edition");
                        
else if(GetSystemMetrics(SM_SERVERR2)!=0 &&  /

                           os.wSuiteMask
==VER_SUITE_STORAGE_SERVER) 

                            vmark
=_T("Storage Server");
                        
break;
                }

                
break;
            
case 6:
                
switch(os.dwMinorVersion){
                    
case 0:
                        
if(os.wProductType!=VER_NT_WORKSTATION && /

                        os.wSuiteMask
==VER_SUITE_DATACENTER) 
                            vmark
=_T("Datacenter Server");
                        
else if(os.wProductType!=VER_NT_WORKSTATION &&  /

                        os.wSuiteMask
==VER_SUITE_ENTERPRISE)
                            vmark
=_T("Enterprise");
                        
else if(os.wProductType==VER_NT_WORKSTATION && /

                           os.wSuiteMask
==VER_SUITE_PERSONAL)  //Windows Vista

                            vmark
=_T("Home");
                        
break;
                }

                
break;
            
default:
                vmark
=_T("");
        }

        
return vmark;
    }

    
else
        
return _T("");

}


另外,操作系统的补丁包名称也可以从szCSDVersion直接获取。

程序编译出来后大家可以用不同版本的兼容模式运行这个程序,来检测结果是不是正确,兼容模式会欺骗GetVersionEx这些API函数,拿Windows 98 兼容模式来说,程序会以为自己是在Windows 98 上运行。

有什么问题请给我留言,如果在本页面下发没有看到有留言请刷新一下页面。

附1:dwPlatformId的值:

VER_PLATFORM_WIN32s (Win32s),

VER_PLATFORM_WIN32_WINDOWS (Windows 
95/Windows 98),

VER_PLATFORM_WIN32_NT (Windows NT
/Windows 2000),

VER_PLATFORM_WIN32_CEHH (Windows CE).

 

附2:wSuiteMask的值:

VER_SUITE_SMALLBUSINESS,

VER_SUITE_ENTERPRISE,

VER_SUITE_BACKOFFICE,

VER_SUITE_COMMUNICATIONS,

VER_SUITE_TERMINAL,

VER_SUITE_SMALLBUSINESS_RESTRICTED,

VER_SUITE_EMBEDDEDNT,

VER_SUITE_DATACENTER.

附3:wProductType的值:

VER_NT_WORKSTATION,

VER_NT_SERVER,

VER_NT_DOMAIN_CONTROLLER.


posted on 2012-10-18 10:19 jackdong 阅读(688) 评论(0)  编辑 收藏 引用 所属分类: Windows编程

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理