Windows API 中有两个函数可以得到系统版本信息:GetVersion和GetVersionEx。
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来查看系统的版本信息了。
下面是一个通过系统版本来判断操作系统名称的例子:
代码片段(2)
[代码] [C/C++]代码
01 | CString getSystemName() |
02 | |
03 | { |
04 | |
05 | SYSTEM_INFO info; //用SYSTEM_INFO结构判断64位AMD处理器 |
06 | GetSystemInfo(&info); //调用GetSystemInfo函数填充结构 |
07 | OSVERSIONINFOEX os; |
08 | os.dwOSVersionInfoSize= sizeof (OSVERSIONINFOEX); /*在调用函数前必须用sizeof(OSVERSIONINFOEXA)填充dwOSVersionInfoSize结构成员*/ |
09 | if (GetVersionEx((OSVERSIONINFO *)&os)) /*调用GetVersionEx函数OSVERSIONINFOEX结构必须将指针类型强制转换*/ |
10 | { |
11 | CString vname; |
12 | |
13 | //下面根据版本信息判断操作系统名称 |
14 | |
15 | switch (os.dwMajorVersion){ //判断主版本号 |
16 | case 4: |
17 | switch (os.dwMinorVersion){ //判断次版本号 |
18 | case 0: |
19 | if (os.dwPlatformId==VER_PLATFORM_WIN32_NT) |
20 | vname=_T( "Microsoft Windows NT 4.0" ); //1996年7月发布 |
21 | else if (os.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS) |
22 | vname=_T( "Microsoft Windows 95" ); |
23 | break ; |
24 | case 10: |
25 | vname=_T( "Microsoft Windows 98" ); |
26 | break ; |
27 | case 90: |
28 | vname=_T( "Microsoft Windows Me" ); |
29 | break ; |
30 | } |
31 | break ; |
32 | case 5: |
33 | switch (os.dwMinorVersion){ //再比较dwMinorVersion的值 |
34 | case 0: |
35 | vname=_T( "Microsoft Windows 2000" ); //1999年12月发布 |
36 | break ; |
37 | case 1: |
38 | vname=_T( "Microsoft Windows XP" ); //2001年8月发布 |
39 | break ; |
40 | case 2: |
41 | if (os.wProductType==VER_NT_WORKSTATION && / |
42 | |
43 | info.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) |
44 | |
45 | vname=_T( "Microsoft Windows XP Professional x64 Edition" ); |
46 | else if (GetSystemMetrics(SM_SERVERR2)==0) |
47 | vname=_T( "Microsoft Windows Server 2003" ); //2003年3月发布 |
48 | else if (GetSystemMetrics(SM_SERVERR2)!=0) |
49 | vname=_T( "Microsoft Windows Server 2003 R2" ); |
50 | break ; |
51 | } |
52 | break ; |
53 | case 6: |
54 | switch (os.dwMinorVersion){ |
55 | case 0: |
56 | if (os.wProductType==VER_NT_WORKSTATION) /* |
57 | |
58 | VER_NT_WORKSTATION是桌面系统 */ |
59 | vname=_T( "Microsoft Windows Vista" ); |
60 | else |
61 | vname=_T( "Microsoft Windows Server 2008" ); //服务器版本 |
62 | break ; |
63 | case 1: |
64 | if (os.wProductType==VER_NT_WORKSTATION) |
65 | vname=_T( "Microsoft Windows 7" ); |
66 | else |
67 | vname=_T( "Microsoft Windows Server 2008 R2" ); |
68 | break ; |
69 | } |
70 | break ; |
71 | default : |
72 | vname=_T( "未知操作系统" ); |
73 | } |
74 | return vname; |
75 | } |
76 | else |
77 | return _T( "" ); |
78 | |
79 | } |
[代码] 返回具体的版本名称
01 | CString getVersionMark() |
02 | |
03 | { |
04 | |
05 | OSVERSIONINFOEX os; |
06 | os.dwOSVersionInfoSize= sizeof (OSVERSIONINFOEX); |
07 | if (GetVersionEx((OSVERSIONINFO *)&os)){ |
08 | CString vmark; |
09 | |
10 | switch (os.dwMajorVersion){ //先判断操作系统版本 |
11 | case 5: |
12 | switch (os.dwMinorVersion){ |
13 | case 0: //Windows 2000 |
14 | if (os.wSuiteMask==VER_SUITE_ENTERPRISE) |
15 | vmark=_T( "Advanced Server" ); |
16 | break ; |
17 | case 1: //Windows XP |
18 | if (os.wSuiteMask==VER_SUITE_EMBEDDEDNT) |
19 | vmark=_T( "Embedded" ); |
20 | else if (os.wSuiteMask==VER_SUITE_PERSONAL) |
21 | vmark=_T( "Home Edition" ); |
22 | else |
23 | vmark=_T( "Professional" ); |
24 | break ; |
25 | case 2: |
26 | if (GetSystemMetrics(SM_SERVERR2)==0 && / |
27 | |
28 | os.wSuiteMask==VER_SUITE_BLADE) //Windows Server 2003 |
29 | vmark=_T( "Web Edition" ); |
30 | else if (GetSystemMetrics(SM_SERVERR2)==0 && / |
31 | |
32 | os.wSuiteMask==VER_SUITE_COMPUTE_SERVER) |
33 | vmark=_T( "Compute Cluster Edition" ); |
34 | else if (GetSystemMetrics(SM_SERVERR2)==0 && / |
35 | |
36 | os.wSuiteMask==VER_SUITE_STORAGE_SERVER) |
37 | vmark=_T( "Storage Server" ); |
38 | else if (GetSystemMetrics(SM_SERVERR2)==0 && / |
39 | |
40 | os.wSuiteMask==VER_SUITE_DATACENTER) |
41 | vmark=_T( "Datacenter Edition" ); |
42 | else if (GetSystemMetrics(SM_SERVERR2)==0 && / |
43 | |
44 | os.wSuiteMask==VER_SUITE_ENTERPRISE) |
45 | vmark=_T( "Enterprise Edition" ); |
46 | else if (GetSystemMetrics(SM_SERVERR2)!=0 && / |
47 | |
48 | os.wSuiteMask==VER_SUITE_STORAGE_SERVER) /* |
49 | |
50 | Windows Server 2003 R2*/ |
51 | |
52 | vmark=_T( "Storage Server" ); |
53 | break ; |
54 | } |
55 | break ; |
56 | case 6: |
57 | switch (os.dwMinorVersion){ |
58 | case 0: |
59 | if (os.wProductType!=VER_NT_WORKSTATION && / |
60 | |
61 | os.wSuiteMask==VER_SUITE_DATACENTER) /* |
62 | |
63 | Windows Server 2008*/ |
64 | vmark=_T( "Datacenter Server" ); |
65 | else if (os.wProductType!=VER_NT_WORKSTATION && / |
66 | |
67 | os.wSuiteMask==VER_SUITE_ENTERPRISE) |
68 | vmark=_T( "Enterprise" ); |
69 | else if (os.wProductType==VER_NT_WORKSTATION && / |
70 | |
71 | os.wSuiteMask==VER_SUITE_PERSONAL) //Windows Vista |
72 | |
73 | vmark=_T( "Home" ); |
74 | break ; |
75 | } |
76 | break ; |
77 | default : |
78 | vmark=_T( "" ); |
79 | } |
80 | return vmark; |
81 | } |
82 | else |
83 | return _T( "" ); |
84 | |
85 | } |