您的位置:首页 > 其它

如何得到Windows操作系统版本信息(包括2003 R2、Vista和Windows 2008 Server)

2007-11-30 09:25 609 查看
在程序中判断Windows版本这本应该是一个极其简单的API就能完成的工作,但由于微软的失误,使得Windows操作系统家族的版本正变得混乱不堪,一个最新的例子是Windows Vista和Windows 2008 Server的版本均为6.0。上世纪90年代Windows 9x和Windows NT的版本混乱主要是因为程序员的错误(或失误)导致的,那么这一次的版本混乱又是因为什么导致的?如果是某些人为的决定导致这样的结果,我只能说这个决定是极其愚蠢的,因为这个愚蠢的决定已经导致版本的意义完全失去了。
废话不多说了,直接贴代码,以下代码可在Vs2005/Vs2008下编译通过。

#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <stdio.h>

#ifndef WSTR
#define WSTR(x) L##x
#endif

#ifndef SM_SERVERR2
#define SM_SERVERR2 89
#endif

// 前置声明
WCHAR* GetOperationSystemInfoOld( WCHAR* szBuffer,size_t szLength);

// GetNativeSystemInfo函数原型(WOW64) (XP,Vista,2003,2008)
typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO lpSystemInfo);

// GetProductInfo函数原型(Vista/2008)
typedef BOOL (WINAPI *PGPI)(DWORD dwOSMajorVersion, DWORD dwOSMinorVersion, DWORD dwSpMajorVersion, DWORD dwSpMinorVersion, PDWORD pdwReturnedProductType);

// ProductType常量
#define PRODUCT_UNDEFINED 0x00000000 // An unknown product
#define PRODUCT_ULTIMATE 0x00000001 // Ultimate Edition
#define PRODUCT_HOME_BASIC 0x00000002 // Home Basic Edition
#define PRODUCT_HOME_PREMIUM 0x00000003 // Home Premium Edition
#define PRODUCT_ENTERPRISE 0x00000004 // Enterprise Edition
#define PRODUCT_HOME_BASIC_N 0x00000005 // Home Basic Edition
#define PRODUCT_BUSINESS 0x00000006 // Business Edition
#define PRODUCT_STANDARD_SERVER 0x00000007 // Server Standard Edition (full installation)
#define PRODUCT_DATACENTER_SERVER 0x00000008 // Server Datacenter Edition (full installation)
#define PRODUCT_SMALLBUSINESS_SERVER 0x00000009 // Small Business Server
#define PRODUCT_ENTERPRISE_SERVER 0x0000000A // Server Enterprise Edition (full installation)
#define PRODUCT_STARTER 0x0000000B // Starter Edition
#define PRODUCT_DATACENTER_SERVER_CORE 0x0000000C // Server Datacenter Edition (core installation)
#define PRODUCT_STANDARD_SERVER_CORE 0x0000000D // Server Standard Edition (core installation)
#define PRODUCT_ENTERPRISE_SERVER_CORE 0x0000000E // Server Enterprise Edition (core installation)
#define PRODUCT_ENTERPRISE_SERVER_IA64 0x0000000F // Server Enterprise Edition for Itanium-based Systems
#define PRODUCT_BUSINESS_N 0x00000010 // Business Edition
#define PRODUCT_WEB_SERVER 0x00000011 // Web Server Edition (full installation)
#define PRODUCT_CLUSTER_SERVER 0x00000012 // Cluster Server Edition
#define PRODUCT_HOME_SERVER 0x00000013 // Home Server Edition
#define PRODUCT_STORAGE_EXPRESS_SERVER 0x00000014 // Storage Server Express Edition
#define PRODUCT_STORAGE_STANDARD_SERVER 0x00000015 // Storage Server Standard Edition
#define PRODUCT_STORAGE_WORKGROUP_SERVER 0x00000016 // Storage Server Workgroup Edition
#define PRODUCT_STORAGE_ENTERPRISE_SERVER 0x00000017 // Storage Server Enterprise Edition
#define PRODUCT_SERVER_FOR_SMALLBUSINESS 0x00000018 // Server for Small Business Edition
#define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM 0x00000019 // Small Business Server Premium Edition
#define PRODUCT_HOME_PREMIUM_N 0x0000001A // Home Premium Edition
#define PRODUCT_ENTERPRISE_N 0x0000001B // Enterprise Edition
#define PRODUCT_ULTIMATE_N 0x0000001C // Ultimate Edition
#define PRODUCT_WEB_SERVER_CORE 0x0000001D // Web Server Edition (core installation)
#define PRODUCT_UNLICENSED 0xABCDABCD // Unlicensed edition

/// <summary>
/// 获得操作系统的信息(2000以前)。
/// </summary>
/// <param name="szBuffer">
/// 用于保存信息的缓冲区(必须足够大)。
/// </param>
/// <returns>
/// 返回操作系统信息。
/// </returns>
WCHAR* GetOperationSystemInfoOld( WCHAR* szBuffer,size_t szLength)
{
// 获得操作系统版本信息
OSVERSIONINFOW osvi = { 0 };
osvi.dwOSVersionInfoSize = sizeof( OSVERSIONINFOW );
if( !GetVersionExW( &osvi ) )
{
szBuffer[0] = WSTR( '' );
return szBuffer;
}
LPWSTR pszTemp = szBuffer;
size_t szTempLen = szLength;
int iLength = 0;

// Windows Me, Windows 98, or Windows 95
if( osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
{
if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion < 10 )
{
iLength = swprintf ( pszTemp,szTempLen, WSTR("Microsoft Windows 95 ") );
szTempLen -= iLength;
pszTemp += iLength;
if ( osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B' )
{
iLength = swprintf( pszTemp,szTempLen, WSTR("OSR2 ") );
szTempLen -= iLength;
pszTemp += iLength;
}
}
else if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
{
iLength = swprintf ( pszTemp,szTempLen, WSTR("Microsoft Windows 98 ") );
szTempLen -= iLength;
pszTemp += iLength;

if ( osvi.szCSDVersion[1] == 'A' )
{
iLength = swprintf( pszTemp,szTempLen, WSTR("SE ") );
szTempLen -= iLength;
pszTemp += iLength;
}
}
else if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
{
iLength = swprintf ( pszTemp,szTempLen, WSTR("Microsoft Windows Millennium Edition ") );
szTempLen -= iLength;
pszTemp += iLength;
}
}
else if( osvi.dwPlatformId == VER_PLATFORM_WIN32_NT )
{
if ( osvi.dwMajorVersion <= 4 )
{
iLength = swprintf( pszTemp,szTempLen, WSTR("Microsoft Windows NT"));
szTempLen -= iLength;
pszTemp += iLength;

// 从注册表获取更详细信息
HKEY hKey = NULL;
WCHAR szProductType[256] = { 0 };
DWORD dwBufLen = 256*sizeof(WCHAR);
RegOpenKeyExW( HKEY_LOCAL_MACHINE, WSTR("SYSTEM/CurrentControlSet/Control/ProductOptions"), 0, KEY_QUERY_VALUE, &hKey );
RegQueryValueExW( hKey, WSTR("ProductType"), NULL, NULL,(LPBYTE) szProductType, &dwBufLen);
RegCloseKey( hKey );

iLength = 0;
if ( lstrcmpiW( WSTR("WINNT"), szProductType) == 0 )
iLength = swprintf( pszTemp,szTempLen, WSTR("Professional ") );
else if ( lstrcmpiW( WSTR("LANMANNT"), szProductType) == 0 )
iLength = swprintf( pszTemp,szTempLen, WSTR("Server ") );
else if( lstrcmpiW( WSTR("SERVERNT"), szProductType) == 0 )
iLength = swprintf( pszTemp,szTempLen, WSTR("Advanced Server ") );

szTempLen -= iLength;
pszTemp += iLength;

// 获取补丁包信息
iLength = swprintf ( pszTemp,szTempLen, WSTR("version %d.%d %s (Build %d)"),
osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.szCSDVersion,osvi.dwBuildNumber & 0xFFFF);
szTempLen -= iLength;
pszTemp += iLength;
}
}

// 未知系统
if( pszTemp == szBuffer )
{
iLength = swprintf ( pszTemp,szTempLen, WSTR("Microsoft Windows Unknown Edition,%s (%d.%d build %d)"),osvi.szCSDVersion,osvi.dwMajorVersion,osvi.dwMajorVersion,osvi.dwBuildNumber);
szTempLen -= iLength;
pszTemp += iLength;
}

return szBuffer;
}

/// <summary>
/// 获得操作系统的信息。
/// </summary>
/// <param name="szBuffer">
/// 用于保存信息的缓冲区(必须足够大)。
/// </param>
/// <returns>
/// 返回操作系统信息。
/// </returns>
WCHAR* GetOperationSystemInfo( WCHAR* szBuffer,size_t szLength)
{
OSVERSIONINFOEXW osvi = { 0 };
SYSTEM_INFO si = { 0 };
LPWSTR pszTemp = szBuffer;
size_t szTempLen = szLength;
int iLength = 0;
if( szBuffer == NULL || szLength == 0 ) return szBuffer;

// 首先尝试使用OSVERSIONINFOEX结构(Windows 2000及以上支持)
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
if( !GetVersionExW ((OSVERSIONINFOW *) &osvi) )
{
// 使用OSVERSIONINFO(Windows95以上支持)
return GetOperationSystemInfoOld( szBuffer,szLength );
}

// 获得系统信息
PGNSI pGetNativeSystemInfo = (PGNSI) GetProcAddress( GetModuleHandleW(WSTR("kernel32.dll")), "GetNativeSystemInfo");
if( pGetNativeSystemInfo != NULL )
(*pGetNativeSystemInfo)( &si );
else
GetSystemInfo(&si);

// 检查操作系统的版本信息
if( osvi.dwPlatformId != VER_PLATFORM_WIN32_NT )
{
iLength = swprintf ( pszTemp,szTempLen, WSTR("Microsoft Windows Unknown Edition,%s (%d.%d build %d)"),osvi.szCSDVersion,osvi.dwMajorVersion,osvi.dwMajorVersion,osvi.dwBuildNumber);
szTempLen -= iLength;
pszTemp += iLength;
return szBuffer;
}

// ASSERT( osvi.dwMajorVersion > 4 );
if( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 ) // 5.0 Windows 2000
{
iLength = swprintf ( pszTemp,szTempLen, WSTR("Microsoft Windows 2000 ") );
szTempLen -= iLength;
pszTemp += iLength;

// 详细版本信息
if ( osvi.wProductType == VER_NT_WORKSTATION )
{
iLength = swprintf ( pszTemp,szTempLen, WSTR("Professional ") );
}
else
{
if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
iLength = swprintf ( pszTemp,szTempLen,WSTR( "Datacenter Server" ));
else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
iLength = swprintf ( pszTemp,szTempLen,WSTR( "Advanced Server" )) ;
else
iLength = swprintf ( pszTemp,szTempLen,WSTR( "Server" ));
}
szTempLen -= iLength;
pszTemp += iLength;
}
else if( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 ) // 5.1 XP
{
iLength = swprintf ( pszTemp,szTempLen, WSTR("Microsoft Windows XP ") );
szTempLen -= iLength;
pszTemp += iLength;

// 详细版本信息
if( osvi.wSuiteMask & VER_SUITE_PERSONAL )
iLength = swprintf ( pszTemp,szTempLen, WSTR( "Home Edition" ));
else
iLength = swprintf ( pszTemp,szTempLen, WSTR( "Professional" ));
szTempLen -= iLength;
pszTemp += iLength;
}
else if( osvi.dwMajorVersion == 5 &&osvi.dwMinorVersion == 2 ) // 5.2 2003
{
if( GetSystemMetrics(SM_SERVERR2) )
iLength = swprintf ( pszTemp,szTempLen, WSTR( "Windows Server 2003 R2 "));
else if ( osvi.wSuiteMask==VER_SUITE_STORAGE_SERVER )
iLength = swprintf ( pszTemp,szTempLen, WSTR( "Windows Storage Server 2003 "));
else if( osvi.wProductType == VER_NT_WORKSTATION && si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 )
iLength = swprintf ( pszTemp,szTempLen, WSTR( "Windows XP Professional x64 Edition"));
else
iLength = swprintf ( pszTemp,szTempLen, WSTR("Windows Server 2003 "));
szTempLen -= iLength;
pszTemp += iLength;

// 详细版本信息
iLength = 0;
if ( osvi.wProductType != VER_NT_WORKSTATION )
{
if ( si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64 )
{
if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
iLength = swprintf ( pszTemp,szTempLen, WSTR( "Datacenter Edition for Itanium-based Systems" ));
else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
iLength = swprintf ( pszTemp,szTempLen, WSTR( "Enterprise Edition for Itanium-based Systems" ));
}
else if ( si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 )
{
if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
iLength = swprintf ( pszTemp,szTempLen, WSTR( "Datacenter x64 Edition" ));
else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
iLength = swprintf ( pszTemp,szTempLen, WSTR( "Enterprise x64 Edition" ));
else
iLength = swprintf ( pszTemp,szTempLen, WSTR( "Standard x64 Edition" ));
}
else
{
if ( osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER )
iLength = swprintf ( pszTemp,szTempLen, WSTR( "Compute Cluster Edition" ));
else if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
iLength = swprintf ( pszTemp,szTempLen, WSTR( "Datacenter Edition" ));
else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
iLength = swprintf ( pszTemp,szTempLen, WSTR( "Enterprise Edition" ));
else if ( osvi.wSuiteMask & VER_SUITE_BLADE )
iLength = swprintf ( pszTemp,szTempLen, WSTR( "Web Edition" ));
else
iLength = swprintf ( pszTemp,szTempLen, WSTR( "Standard Edition" ));
}
}
szTempLen -= iLength;
pszTemp += iLength;
}
else if( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0 ) // 6.0 vista and 2008
{
if( osvi.wProductType == VER_NT_WORKSTATION )
iLength = swprintf ( pszTemp,szTempLen, WSTR("Windows Vista "));
else
iLength = swprintf ( pszTemp,szTempLen, WSTR("Windows Server 2008 " ));
szTempLen -= iLength;
pszTemp += iLength;

// 获得GetProductInfo函数原型
PGPI pGetProductInfo = NULL;
pGetProductInfo = (PGPI) GetProcAddress( GetModuleHandleW(WSTR("kernel32.dll")), "GetProductInfo");
if( pGetProductInfo != NULL )
{
DWORD dwProductType = 0;
(*pGetProductInfo)( 6,0,0,0,&dwProductType);
switch( dwProductType )
{
case PRODUCT_ULTIMATE:
case PRODUCT_ULTIMATE_N:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Ultimate Edition" ));
break;
case PRODUCT_HOME_PREMIUM:
case PRODUCT_HOME_PREMIUM_N:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Home Premium Edition" ));
break;
case PRODUCT_HOME_BASIC:
case PRODUCT_HOME_BASIC_N:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Home Basic Edition" ));
break;
case PRODUCT_HOME_SERVER:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Home Server Edition" ));
break;
case PRODUCT_ENTERPRISE:
case PRODUCT_ENTERPRISE_N:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Enterprise Edition" ));
break;
case PRODUCT_BUSINESS:
case PRODUCT_BUSINESS_N:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Business Edition" ));
break;
case PRODUCT_STARTER:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Starter Edition" ));
break;
case PRODUCT_CLUSTER_SERVER:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Cluster Server Edition" ));
break;
case PRODUCT_DATACENTER_SERVER:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Datacenter Edition" ));
break;
case PRODUCT_DATACENTER_SERVER_CORE:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Datacenter Edition (core installation)" ));
break;
case PRODUCT_ENTERPRISE_SERVER:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Enterprise Edition" ));
break;
case PRODUCT_ENTERPRISE_SERVER_CORE:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Enterprise Edition (core installation)" ));
break;
case PRODUCT_ENTERPRISE_SERVER_IA64:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Enterprise Edition for Itanium-based Systems" ));
break;
case PRODUCT_SMALLBUSINESS_SERVER:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Small Business Server" ));
break;
case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Small Business Server Premium Edition" ));
break;
case PRODUCT_SERVER_FOR_SMALLBUSINESS:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Server for Small Business Edition" ));
break;
case PRODUCT_STANDARD_SERVER:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Standard Edition" ));
break;
case PRODUCT_STANDARD_SERVER_CORE:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Standard Edition (core installation)" ));
break;
case PRODUCT_WEB_SERVER:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Web Server Edition" ));
break;
case PRODUCT_WEB_SERVER_CORE:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Web Server Edition (core installation)" ));
break;
case PRODUCT_STORAGE_ENTERPRISE_SERVER:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Storage Server Enterprise Edition" ));
break;
case PRODUCT_STORAGE_EXPRESS_SERVER:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Storage Server Express Edition" ));
break;
case PRODUCT_STORAGE_STANDARD_SERVER:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Storage Server Standard Edition" ));
break;
case PRODUCT_STORAGE_WORKGROUP_SERVER:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Storage Server Workgroup Edition" ));
break;
case PRODUCT_UNLICENSED:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Unlicensed Edition" ));
break;
default:
iLength = swprintf ( pszTemp,szTempLen, WSTR("Unknown Edition" ));
break;
}
szTempLen -= iLength;
pszTemp += iLength;
}

// 详细版本信息
iLength = 0;
if ( si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 )
iLength = swprintf ( pszTemp,szTempLen, WSTR( ", 64-bit" ));
else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL )
iLength = swprintf ( pszTemp,szTempLen, WSTR(", 32-bit"));
szTempLen -= iLength;
pszTemp += iLength;
}
else
{
iLength = swprintf ( pszTemp,szTempLen, WSTR("Microsoft Windows Unknown Edition,%s (%d.%d build %d)"),osvi.szCSDVersion,osvi.dwMajorVersion,osvi.dwMajorVersion,osvi.dwBuildNumber);
szTempLen -= iLength;
pszTemp += iLength;
return szBuffer;
}

// 补丁包和创建版本
iLength = swprintf ( pszTemp,szTempLen, WSTR(", %s (Build %d)"), osvi.szCSDVersion,osvi.dwBuildNumber);
szTempLen -= iLength;
pszTemp += iLength;

// 返回信息
return szBuffer;
}

int _tmain(int argc, _TCHAR* argv[])
{
WCHAR szInfo[1024] = { 0 };
wprintf(L"%s ",GetOperationSystemInfo( szInfo,1024 ));
return 0;

}

以上程序在我的机器上运行结果为:Windows Server 2003 Enterprise Edition, Service Pack 2 (Build 3790)。因为没有条件在所有的操作系统上进行测试,有条件的朋友可以帮忙测试一下,看看有什么错误和疏漏没有。
为了方便大家,将整理的Windows版本变迁历史也列出来(如有错误,还请指正):

Windows版本变迁

Windows产品MajorMinorPlatformIDBuildNumber(n)
Windows 95401(VER_PLATFORM_WIN32_WINDOWS)950
Windows 95 SP1401950 <n<=1080
Windows 95 OSR24<101>1080
Windows 9841011998
Windows 98 SP141011998<n<2183
Windows 98 SE4101>=2183
Windows Me49013000
Windows NT 3.513512(VER_PLATFORM_WIN32_NT)1057
Windows NT 4.04021381
Windows 20005022195
Windows XP5122600
Windows 20035223790(?)
Windows Vista602
Windows 2008 602
Windows CE 1.0103
Windows CE 2.0203
Windows CE 2.1213
Windows CE 3.030 3
Windows FutureXYZ
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐