如何确定用户运行的是哪个Wi n d o w s 版本?即GetVersion()与GetVersionEx()的区别.

应用程序常常需要确定用户运行的是哪个Wi n d o w s 版本。例如,通过调用安全性函数,应用程序就能利用它的安全特性。但是这些函数只有在Windows 2000 上才能得到全面的实现。

Windows API 拥有下面的G e t Ve r s i o n 函数:

DWORD GetVersion();
该函数已经有相当长的历史了。最初它是为1 6 位Wi n d o w s 设计的。它的作用很简单,在高位字中返回M S - D O S 版本号,在低位字中返回Wi n d o w s 版本号。对于每个字来说,高位字节代表主要版本号,低位字节代表次要版本号。

但是,编写该代码的程序员犯了一个小小的错误,函数的编码结果使得Wi n d o w s 的版本号颠倒了,即主要版本号位于低位字节,而次要版本号位于高位字节。由于许多程序员已经开始使用该函数,M i c r o s o f t 不得不保持函数的原样,并修改了文档,以说明这个错误。

由于围绕着G e t Ve r s i o n 函数存在着各种混乱,因此M i c r o s o f t 增加了一个新函数G e t Ve r s i o n E x :

BOOL GetVersionEx(POSVERSIONINFO pVersionInformation);
该函数要求在应用程序中指定一个O S V E R S I O N I N F O E X 结构,并将该结构的地址传递给G e t Ve r s i o n E x 。O S V E R S I O N I N F O E X 的结构如下所示:
typedef struct
{
   DWORD dwOSVersionInfoSize;
   DWORD dwMajorVersion;
   DWORD dwMinorVersion;
   DWORD dwBuildNumber;
   DWORD dwPlatformId;
   TCHAR szCSDVersion[128];
   WORD wServicePackMajor;
   WORD wServicePackMinor;
   WORD wSuiteMask;
   BYTE wProductType;
   BYTE wReserved;
} OSVERSIONINFOEX, *POSVERSIONINFOEX;
O S V E R S I O N I N F O E X 结构在Windows 2000 中是个新结构。Wi n d o w s 的其他版本使用较老的O S V E R S I O N I N F O 结构,它没有服务程序包、程序组屏蔽、产品类型和保留成员。

注意,对于系统的版本号中的每个成分来说,该结构拥有不同的成员。这样做的目的是,程序员不必提取低位字、高位字、低位字节和高位字节,因此应用程序能够更加容易地对它们期望的版本号与主机系统的版本号进行比较。表4 - 4 描述了O S V E R S I O N I N F O E X 结构的成员。

表4-4 OSVERSIONINFOEX 结构的成员

成员描述
dwOSVersionInfoSize在调用GetVersionEx 函数之前,必须置为sizeof(OSVERSIONINFO)或sizeof(OSVERSIONINFOEX)
dwMajorVersion主系统的主要版本号
dwMinorVersion主系统的次要版本号
dwBuildNumber当前系统的构建号
dwPlatformId用于标识当前系统支持的平台。它可以是VER_PLATFORM_WIN32s (Win32s), VER_PLATFORM_WIN32_WINDOWS (Windows 95/Windows 98), VER_PLATFORM_WIN32_NT (Windows NT/Windows 2000), or VER_PLATFORM_WIN32_CEHH (Windows CE).
szCSDVersion本域包含了附加文本,用于提供关于已经安装的操作系统的详细信息
wServicePackMajor最新安装的服务程序包的主要版本号
wServicePackMinor最新安装的服务程序包的次要版本号
wSuiteMask用于标识系统上存在哪个程序组
(VER_SUITE_SMALLBUSINESS,
VER_SUITE_ENTERPRISE,
VER_SUITE_BACKOFFICE,
VER_SUITE_COMMUNICATIONS,
VER_SUITE_TERMINAL,
VER_SUITE_SMALLBUSINESS_RESTRICTED,
VER_SUITE_EMBEDDEDNT,and
VER_SUITE_DATACENTER).
wProductType用于标识安装了下面的哪个操作系统:VER_NT_WORKSTATION, VER_NT_SERVER, or VER_NT_DOMAIN_CONTROLLER.
wReserved留作将来使用

为了使操作更加容易,Windows 2000 提供了一个新的函数,即Ve r i f y Ve r s i o n I n f o ,用于对主机系统的版本与你的应用程序需要的版本进行比较:

BOOL VerifyVersionInfo(
   POSVERSIONINFOEX pVersionInformation,
   DWORD dwTypeMask,
   DWORDLONG dwlConditionMask);
若要使用该函数,必须指定一个O S V E R S I O N I N F O E X 结构,将它的d w O S Ve r s i o n I n f o S i z e 成员初始化为该结构的大小,然后对该结构中的其他成员(这些成员对你的应用程序来说很重要)进行初始化。当调用Ve r i f y Ve r s i o n I n f o 时,d w Ty p e M a s k 参数用于指明该结构的哪些成员已经进行了初始化。d w Ty p e M a s k 参数是用O R 连接在一起的下列标志中的任何一个标志:
V E R _ M I N O RV E R S I O N ,V E R _ M A J O RV E R S I O N ,V E R _ B U I L D N U M B E R ,V E R _ P L AT F O R M I D ,VER_ SERV I C E PA C K M I N O R ,V E R _ S E RV I C E PA C K M A J O R ,V E R _ S U I T E N A M E ,VER_PRODUCT_ TYPE 。最后一个参数d w l C o n d i t i o n M a s k 是个6 4 位值,用于控制该函数如何将系统的版本信息与需要的信息进行比较。

d w l C o n d i t i o n M a s k 描述了如何使用一组复杂的位组合进行的比较。若要创建需要的位组合,可以使用V E R _ S E T _ C O N D I T I O N 宏:

VER_SET_CONDITION(
   DWORDLONG dwlConditionMask,
   ULONG dwTypeBitMask,
   ULONG dwConditionMask)
第一个参数d w l C o n d i t i o n M a s k 用于标识一个变量,该变量的位是要操作的那些位。请注意,不必传递该变量的地址,因为V E R _ S E T _ C O N D I T I O N 是个宏,不是一个函数。d w Ty p e B i t M a s k 参数用于指明想要比较的O S V E R S I O N I N F O E X 结构中的单个成员。若要比较多个成员,必须多次调用V E R _ S E T _ C O N D I T I O N 宏,每个成员都要调用一次。传递给Ve r i f y Ve r s i o n I n f o 的d w Ty p e M a s k 参数(V E R _ M I N O RV E R S I O N ,V E R _ B U I L D N U M B E R 等)的标志与用于V E R _ S E T _ C O N D I T I O N 的d w Ty p e B i t M a s k 参数的标志是相同的。

V E R _ S E T _ C O N D I T I O N 的最后一个参数d w C o n d i t i o n M a s k 用于指明想如何进行比较。它可以是下列值之一:V E R _ E Q U A L ,V E R _ G R E AT E R ,V E R _ G R E AT E R _ E Q U A L ,V E R _ L E S S 或V E R _ L E S S _ E Q U A L 。请注意,当比较V E R _ P R O D U C T _ T Y P E 信息时,可以使用这些值。例如,V E R _ N T _ W O R K S TAT I O N 小于V E R _ N T _ S E RV E R 。但是对于V E R _ S U I T E N A M E 信息来说,不能使用这些测试值。相反,必须使用V E R _ A N D (所有程序组都必须安装)或V E R _ O R (至少必须安装程序组产品中的一个产品)。

当建立一组条件后,可以调用Ve r i f y Ve r s i o n I n f o 函数,如果调用成功(如果主机系统符合应用程序的所有要求),则返回非零值。如果Ve r i f y Ve r s i o n I n f o 返回0 ,那么主机系统不符合要求,或者表示对该函数的调用不正确。通过调用G e t L a s t E r r o r 函数,就能确定该函数为什么返回0 。如果G e t L a s t E r r o r 返回E R R O R _ O L D _ W I N _ V E R S I O N ,那么对该函数的调用是正确的,但是系统没有满足要求。

下面是如何测试主机系统是否正是Windows 2000 的一个例子:

//Prepare the OSVERSIONINFOEX structure 
//to indicate Windows 2000.
OSVERSIONINFOEX osver = { 0 };
osver.dwOSVersionInfoSize = sizeof(osver);
osver.dwMajorVersion = 5;

osver.dwMinorVersion = 0;
osver.dwPlatformId = VER_PLATFORM_WIN32_NT;

//Prepare the condition mask.
//You MUST initialize this to 0.
DWORDLONG dwlConditionMask = 0;     

VER_SET_CONDITION(dwlConditionMask,
   VER_MAJORVERSION,VER_EQUAL);
   
VER_SET_CONDITION(dwlConditionMask,
   VER_MINORVERSION,VER_EQUAL);
   
VER_SET_CONDITION(dwlConditionMask,
   VER_PLATFORMID,VER_EQUAL);

//Perform the version test.
if(VerifyVersionInfo(&osver,
   VER_MAJORVERSION | VER_MINORVERSION | VER_PLATFORMID,
   dwlConditionMask))
{
   //The host system is windows 2000 exactly.
}
else
{
   //The host system is NOT windows 2000.
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值