注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

银河军团大本营

光荣的军团,永远的丰碑 <坚持原创>

 
 
 

日志

 
 

获取Windows版本信息(可能史上最全最精确^o^)  

2012-09-10 14:05:01|  分类: 编程小技巧 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

  在网上查了不少资料,总结了一个可能是史上最全最精确的方法来获取Windows版本信息。

  在google里搜索“msdn os version”及“获取Windows版本”可得到大量的资料,以下代码就是从网上搜集的资料整理而成(代码在VC++ 2005/VC++ 2005 Express/VS2008/VS2010以及VS2013中编译通过,为了方便在64位下编译,所以改成不用预编译的版本,如果要用预编译,请去掉 //#include "stdafx.h" 前的//):

/*****************************************************************************
Operating System Version PlatformID
Windows 10 10.0 VER_PLATFORM_WIN32_NT
Windows Server 2016 10.0 VER_PLATFORM_WIN32_NT
Windows 10 Preview 6.4 VER_PLATFORM_WIN32_NT
Windows 8.1 6.3 VER_PLATFORM_WIN32_NT
Windows Server 2012 R2 6.3 VER_PLATFORM_WIN32_NT
Windows 8 6.2 VER_PLATFORM_WIN32_NT (=2)
Windows Server 2012 6.2 VER_PLATFORM_WIN32_NT
Windows 7 6.1 VER_PLATFORM_WIN32_NT
Windows Server 2008 R2 6.1 VER_PLATFORM_WIN32_NT
Windows Server 2008 6.0 VER_PLATFORM_WIN32_NT
Windows Vista 6.0 VER_PLATFORM_WIN32_NT
Windows Server 2003 R2 5.2 VER_PLATFORM_WIN32_NT
Windows Server 2003 5.2 VER_PLATFORM_WIN32_NT
Windows XP 64-Bit Edition 5.2 VER_PLATFORM_WIN32_NT
Windows XP 5.1 VER_PLATFORM_WIN32_NT
Windows 2000 5.0 VER_PLATFORM_WIN32_NT
Windows NT 4.0 4.0 VER_PLATFORM_WIN32_NT
Windows NT 3.51 3.51 ? VER_PLATFORM_WIN32_NT
Windows Millennium Edition 4.90 VER_PLATFORM_WIN32_WINDOWS (=1)
Windows 98 4.10 VER_PLATFORM_WIN32_WINDOWS
Windows 95 4.0 VER_PLATFORM_WIN32_WINDOWS
Windows 3.1 3.1 ? VER_PLATFORM_WIN32s (=0)
*****************************************************************************/

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

#pragma comment(lib, "User32.lib")
#pragma comment(lib, "Advapi32.lib") //VS2005 Express needed

#define BUFSIZE 256

#define PRODUCT_ULTIMATE 0x00000001

#define PRODUCT_HOME_BASIC 0x00000002
#define PRODUCT_HOME_PREMIUM 0x00000003
#define PRODUCT_ENTERPRISE 0x00000004
#define PRODUCT_HOME_BASIC_N 0x00000005
#define PRODUCT_BUSINESS 0x00000006
#define PRODUCT_STANDARD_SERVER 0x00000007
#define PRODUCT_DATACENTER_SERVER 0x00000008
#define PRODUCT_SMALLBUSINESS_SERVER 0x00000009
#define PRODUCT_ENTERPRISE_SERVER 0x0000000A
#define PRODUCT_STARTER 0x0000000B
#define PRODUCT_DATACENTER_SERVER_CORE 0x0000000C
#define PRODUCT_STANDARD_SERVER_CORE 0x0000000D
#define PRODUCT_ENTERPRISE_SERVER_CORE 0x0000000E
#define PRODUCT_ENTERPRISE_SERVER_IA64 0x0000000F
#define PRODUCT_BUSINESS_N 0x00000010
#define PRODUCT_WEB_SERVER 0x00000011
#define PRODUCT_CLUSTER_SERVER 0x00000012
#define PRODUCT_HOME_SERVER 0x00000013
#define PRODUCT_STORAGE_EXPRESS_SERVER 0x00000014
#define PRODUCT_STORAGE_STANDARD_SERVER 0x00000015

#define PRODUCT_STORAGE_WORKGROUP_SERVER 0x00000016
#define PRODUCT_STORAGE_ENTERPRISE_SERVER 0x00000017
#define PRODUCT_SERVER_FOR_SMALLBUSINESS 0x00000018
#define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM 0x00000019
#define PRODUCT_HOME_PREMIUM_N 0x0000001A
#define PRODUCT_ENTERPRISE_N 0x0000001B
#define PRODUCT_ULTIMATE_N 0x0000001C
#define PRODUCT_WEB_SERVER_CORE 0x0000001D
#define PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT 0x0000001E
#define PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY 0x0000001F
#define PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING 0x00000020
#define PRODUCT_SMALLBUSINESS_SERVER_PRIME 0x00000021
#define PRODUCT_HOME_PREMIUM_SERVER 0x00000022
#define PRODUCT_SERVER_FOR_SMALLBUSINESS_V 0x00000023
#define PRODUCT_STANDARD_SERVER_V 0x00000024
#define PRODUCT_DATACENTER_SERVER_V 0x00000025
#define PRODUCT_ENTERPRISE_SERVER_V 0x00000026
#define PRODUCT_DATACENTER_SERVER_CORE_V 0x00000027
#define PRODUCT_STANDARD_SERVER_CORE_V 0x00000028
#define PRODUCT_ENTERPRISE_SERVER_CORE_V 0x00000029
#define PRODUCT_HYPERV 0x0000002A
#define PRODUCT_PROFESSIONAL 0x00000030

#define SM_TABLETPC 86
#define SM_MEDIACENTER 87
#define SM_STARTER 88
#define SM_SERVERR2 89
/*#define VER_SERVER_NT 0x80000000
#define VER_WORKSTATION_NT 0x40000000
#define VER_SUITE_SMALLBUSINESS 0x00000001
#define VER_SUITE_ENTERPRISE 0x00000002
#define VER_SUITE_BACKOFFICE 0x00000004
#define VER_SUITE_COMMUNICATIONS 0x00000008
#define VER_SUITE_TERMINAL 0x00000010
#define VER_SUITE_SMALLBUSINESS_RESTRICTED 0x00000020
#define VER_SUITE_EMBEDDEDNT 0x00000040
#define VER_SUITE_DATACENTER 0x00000080
#define VER_SUITE_SINGLEUSERTS 0x00000100
#define VER_SUITE_PERSONAL 0x00000200
#define VER_SUITE_BLADE 0x00000400
#define VER_SUITE_EMBEDDED_RESTRICTED 0x00000800
#define VER_SUITE_SECURITY_APPLIANCE 0x00001000
#define VER_SUITE_STORAGE_SERVER 0x00002000
#define VER_SUITE_COMPUTE_SERVER 0x00004000*/
#define VER_SUITE_WH_SERVER 0x00008000

typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD);

BOOL GetVersionEx2(LPOSVERSIONINFOW lpVersionInformation)
{
HMODULE hNtDll = GetModuleHandleW(L"NTDLL");
typedef NTSTATUS (NTAPI*tRtlGetVersion)(PRTL_OSVERSIONINFOW povi); // RtlGetVersion prototype
tRtlGetVersion pRtlGetVersion = NULL;
if (hNtDll)
{
pRtlGetVersion = (tRtlGetVersion)GetProcAddress(hNtDll, "RtlGetVersion");
}
if (pRtlGetVersion)
{
return pRtlGetVersion((PRTL_OSVERSIONINFOW)lpVersionInformation) >= 0;
}
return FALSE;
}

BOOL GetOSDisplayString( LPTSTR pszOS)
{
OSVERSIONINFOEX osvi;
SYSTEM_INFO si;
PGNSI pGNSI;
PGPI pGPI;
BOOL bOsVersionInfoEx;
DWORD dwType;

ZeroMemory(&si, sizeof(SYSTEM_INFO));
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));

osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*) &osvi);

if(!bOsVersionInfoEx) return FALSE;

_tprintf(TEXT("GetVersionEx=%d.%d.%d\n"), osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber); //output version info directly

// Call GetNativeSystemInfo if supported or GetSystemInfo otherwise.

pGNSI = (PGNSI) GetProcAddress(
GetModuleHandle(TEXT("kernel32.dll")),
"GetNativeSystemInfo");
if(NULL != pGNSI)
pGNSI(&si);
else GetSystemInfo(&si);

if ( VER_PLATFORM_WIN32_NT==osvi.dwPlatformId &&
osvi.dwMajorVersion > 4 )
{
StringCchCopy(pszOS, BUFSIZE, TEXT("Microsoft "));

if (osvi.dwMajorVersion >= 6)
{ // after Windows 8.1 or later, GetVersionEx function cannot get correct version...
OSVERSIONINFOEXW ovi;
ZeroMemory(&ovi, sizeof(OSVERSIONINFOEXW));
if (!GetVersionEx2((LPOSVERSIONINFOW)&ovi)) return FALSE;
// GetVersionEx2/RtlGetVersion cannot get correct wProductType, so copy it to osvi
osvi.dwMajorVersion = ovi.dwMajorVersion;
osvi.dwMinorVersion = ovi.dwMinorVersion;
osvi.dwBuildNumber = ovi.dwBuildNumber;
_tprintf(TEXT("RtlGetVersion=%d.%d.%d\n"), osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber); //output version info directly
}

// Test for the specific product.
if (osvi.dwMajorVersion > 6)
{
if ( osvi.dwMajorVersion > 10 || osvi.dwMinorVersion > 0 )
{
StringCchCat(pszOS, BUFSIZE, TEXT("Windows 10 Later ")); // for new OS
}
else
{
if( osvi.wProductType == VER_NT_WORKSTATION )
StringCchCat(pszOS, BUFSIZE, TEXT("Windows 10 "));
else
StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2016 " ));
}

}
else if ( osvi.dwMajorVersion == 6 )
{
switch( osvi.dwMinorVersion )
{
case 0:
if( osvi.wProductType == VER_NT_WORKSTATION )
StringCchCat(pszOS, BUFSIZE, TEXT("Windows Vista "));
else
StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2008 " ));
break;
case 1:
if( osvi.wProductType == VER_NT_WORKSTATION )
StringCchCat(pszOS, BUFSIZE, TEXT("Windows 7 "));
else
StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2008 R2 " ));
break;
case 2:
if( osvi.wProductType == VER_NT_WORKSTATION )
StringCchCat(pszOS, BUFSIZE, TEXT("Windows 8 "));
else
StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2012 "));
break;
case 3:
if( osvi.wProductType == VER_NT_WORKSTATION )
StringCchCat(pszOS, BUFSIZE, TEXT("Windows 8.1 "));
else
StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2012 R2 "));
break;
default: // 6.4 ?!
StringCchCat(pszOS, BUFSIZE, TEXT("Windows 10 Preview ")); //?? preview version for windows 10 ?!

}

pGPI = (PGPI) GetProcAddress(
GetModuleHandle(TEXT("kernel32.dll")),
"GetProductInfo");

pGPI( osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType);

switch( dwType )
{
case PRODUCT_ULTIMATE:
StringCchCat(pszOS, BUFSIZE, TEXT("Ultimate Edition" ));
break;
case PRODUCT_PROFESSIONAL:
StringCchCat(pszOS, BUFSIZE, TEXT("Professional" ));
break;
case PRODUCT_HOME_PREMIUM:
StringCchCat(pszOS, BUFSIZE, TEXT("Home Premium Edition" ));
break;
case PRODUCT_HOME_BASIC:
StringCchCat(pszOS, BUFSIZE, TEXT("Home Basic Edition" ));
break;
case PRODUCT_ENTERPRISE:
StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition" ));
break;
case PRODUCT_BUSINESS:
StringCchCat(pszOS, BUFSIZE, TEXT("Business Edition" ));
break;
case PRODUCT_STARTER:
StringCchCat(pszOS, BUFSIZE, TEXT("Starter Edition" ));
break;
case PRODUCT_CLUSTER_SERVER:
StringCchCat(pszOS, BUFSIZE, TEXT("Cluster Server Edition" ));
break;
case PRODUCT_DATACENTER_SERVER:
StringCchCat(pszOS, BUFSIZE, TEXT("Datacenter Edition" ));
break;
case PRODUCT_DATACENTER_SERVER_CORE:
StringCchCat(pszOS, BUFSIZE, TEXT("Datacenter Edition (core installation)" ));
break;
case PRODUCT_ENTERPRISE_SERVER:
StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition" ));
break;
case PRODUCT_ENTERPRISE_SERVER_CORE:
StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition (core installation)" ));
break;
case PRODUCT_ENTERPRISE_SERVER_IA64:
StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition for Itanium-based Systems" ));
break;
case PRODUCT_SMALLBUSINESS_SERVER:
StringCchCat(pszOS, BUFSIZE, TEXT("Small Business Server" ));
break;
case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
StringCchCat(pszOS, BUFSIZE, TEXT("Small Business Server Premium Edition" ));
break;
case PRODUCT_STANDARD_SERVER:
StringCchCat(pszOS, BUFSIZE, TEXT("Standard Edition" ));
break;
case PRODUCT_STANDARD_SERVER_CORE:
StringCchCat(pszOS, BUFSIZE, TEXT("Standard Edition (core installation)" ));
break;
case PRODUCT_WEB_SERVER:
StringCchCat(pszOS, BUFSIZE, TEXT("Web Server Edition" ));
break;
}
}

else if ( /*osvi.dwMajorVersion == 5 &&*/ osvi.dwMinorVersion == 2 )
{
if( GetSystemMetrics(SM_SERVERR2) )
StringCchCat(pszOS, BUFSIZE, TEXT( "Windows Server 2003 R2, "));
else if ( osvi.wSuiteMask & VER_SUITE_STORAGE_SERVER )
StringCchCat(pszOS, BUFSIZE, TEXT( "Windows Storage Server 2003"));
else if ( osvi.wSuiteMask & VER_SUITE_WH_SERVER )
StringCchCat(pszOS, BUFSIZE, TEXT( "Windows Home Server"));
else if( osvi.wProductType == VER_NT_WORKSTATION &&
si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
{
StringCchCat(pszOS, BUFSIZE, TEXT( "Windows XP Professional x64 Edition"));
}
else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2003, "));

// Test for the server type.
if ( osvi.wProductType != VER_NT_WORKSTATION )
{
if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64 )
{
if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter Edition for Itanium-based Systems" ));
else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
StringCchCat(pszOS, BUFSIZE, TEXT( "Enterprise Edition for Itanium-based Systems" ));
}

else if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 )
{
if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter x64 Edition" ));
else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
StringCchCat(pszOS, BUFSIZE, TEXT( "Enterprise x64 Edition" ));
else StringCchCat(pszOS, BUFSIZE, TEXT( "Standard x64 Edition" ));
}

else
{
if ( osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER )
StringCchCat(pszOS, BUFSIZE, TEXT( "Compute Cluster Edition" ));
else if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter Edition" ));
else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
StringCchCat(pszOS, BUFSIZE, TEXT( "Enterprise Edition" ));
else if ( osvi.wSuiteMask & VER_SUITE_BLADE )
StringCchCat(pszOS, BUFSIZE, TEXT( "Web Edition" ));
else StringCchCat(pszOS, BUFSIZE, TEXT( "Standard Edition" ));
}
}
}

else if ( /*osvi.dwMajorVersion == 5 &&*/ osvi.dwMinorVersion == 1 )
{
StringCchCat(pszOS, BUFSIZE, TEXT("Windows XP "));
if( osvi.wSuiteMask & VER_SUITE_PERSONAL )
StringCchCat(pszOS, BUFSIZE, TEXT( "Home Edition" ));
else StringCchCat(pszOS, BUFSIZE, TEXT( "Professional" ));
}

else if ( /*osvi.dwMajorVersion == 5 &&*/ osvi.dwMinorVersion == 0 )
{
StringCchCat(pszOS, BUFSIZE, TEXT("Windows 2000 "));

if ( osvi.wProductType == VER_NT_WORKSTATION )
{
StringCchCat(pszOS, BUFSIZE, TEXT( "Professional" ));
}
else
{
if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter Server" ));
else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
StringCchCat(pszOS, BUFSIZE, TEXT( "Advanced Server" ));
else StringCchCat(pszOS, BUFSIZE, TEXT( "Server" ));
}
}

// Include service pack (if any) and build number.

if( _tcslen(osvi.szCSDVersion) > 0 )
{
StringCchCat(pszOS, BUFSIZE, TEXT(" ") );
StringCchCat(pszOS, BUFSIZE, osvi.szCSDVersion);
}

TCHAR buf[80];

StringCchPrintf( buf, 80, TEXT(" (build %d)"), osvi.dwBuildNumber);
StringCchCat(pszOS, BUFSIZE, buf);

if ( osvi.dwMajorVersion >= 6 )
{
if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 )
StringCchCat(pszOS, BUFSIZE, TEXT( ", 64-bit" ));
else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL )
StringCchCat(pszOS, BUFSIZE, TEXT(", 32-bit"));
}

return TRUE;
}

else
{
return FALSE;
}
}

BOOL GetOldOSVer(LPSTR pszOldOS)
{
OSVERSIONINFOEXA osvi;
BOOL bOsVersionInfoEx;

ZeroMemory(&osvi, sizeof(OSVERSIONINFOEXA));

// Try calling GetVersionEx using the OSVERSIONINFOEX structure.
// If that fails, try using the OSVERSIONINFO structure.
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA);
bOsVersionInfoEx = GetVersionExA ((OSVERSIONINFOA *) &osvi);

if( !bOsVersionInfoEx )
{
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
if (! GetVersionExA ( (OSVERSIONINFOA *) &osvi) )
{
StringCchCatA(pszOldOS, BUFSIZE, "Unknow Windows?");
return FALSE;
}
}

switch (osvi.dwPlatformId)
{
// Test for the Windows NT product family.
case VER_PLATFORM_WIN32_NT:
if (osvi.dwMajorVersion <= 4){
StringCchCatA(pszOldOS, BUFSIZE, "Microsoft Windows NT ");
}else{
return FALSE;
}
break;
// Test for the Windows Me/98/95.
case VER_PLATFORM_WIN32_WINDOWS:
if (osvi.dwMajorVersion == 4)
{
switch (osvi.dwMinorVersion)
{
case 0:
StringCchCatA(pszOldOS, BUFSIZE, "Microsoft Windows 95 ");
if (osvi.szCSDVersion[1]=='C' || osvi.szCSDVersion[1]=='B')
StringCchCatA(pszOldOS, BUFSIZE, "OSR2 " );
break;
case 3: //??
StringCchCatA(pszOldOS, BUFSIZE, "Microsoft Windows 95 OSR2 ");
case 10:
StringCchCatA(pszOldOS, BUFSIZE, "Microsoft Windows 98 ");
if ( osvi.szCSDVersion[1]=='A' || osvi.szCSDVersion[1]=='B')
StringCchCatA(pszOldOS, BUFSIZE, "SE " );
break;
case 90:
StringCchCatA(pszOldOS, BUFSIZE, "Microsoft Windows Millennium Edition ");
break;
}
}
break;
case VER_PLATFORM_WIN32s:
StringCchCatA(pszOldOS, BUFSIZE, "Microsoft Win32s ");
break;
default:
return FALSE;
}

if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
// Test for specific product on Windows NT 4.0 SP6 and later.
if( bOsVersionInfoEx )
{
// Test for the workstation type.
if ( osvi.wProductType == VER_NT_WORKSTATION)
{
if( osvi.dwMajorVersion == 4 )
StringCchCatA(pszOldOS, BUFSIZE, "Workstation 4.0 " );
else if( osvi.wSuiteMask & VER_SUITE_PERSONAL )
StringCchCatA(pszOldOS, BUFSIZE, "Home Edition " );
else StringCchCatA(pszOldOS, BUFSIZE, "Professional " );
}
// Test for the server type.
else if ( osvi.wProductType == VER_NT_SERVER ||
osvi.wProductType == VER_NT_DOMAIN_CONTROLLER )
{
// Windows NT 4.0
if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
StringCchCatA(pszOldOS, BUFSIZE, "Server 4.0, Enterprise Edition " );
else StringCchCatA(pszOldOS, BUFSIZE, "Server 4.0 " );
}
}
// Test for specific product on Windows NT 4.0 SP5 and earlier
else
{
HKEY hKey;
TCHAR szProductType[BUFSIZE];
DWORD dwBufLen=BUFSIZE*sizeof(TCHAR);
LONG lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
TEXT("SYSTEM\\CurrentControlSet\\Control\\ProductOptions"), 0, KEY_QUERY_VALUE, &hKey );
if( lRet != ERROR_SUCCESS )
return FALSE;

lRet = RegQueryValueEx( hKey, TEXT("ProductType"),
NULL, NULL, (LPBYTE) szProductType, &dwBufLen);
RegCloseKey( hKey );

if( (lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE*sizeof(TCHAR)) )
return FALSE;

if ( lstrcmpi( TEXT("WINNT"), szProductType) == 0 )
StringCchCatA(pszOldOS, BUFSIZE, "Workstation " );
if ( lstrcmpi( TEXT("LANMANNT"), szProductType) == 0 )
StringCchCatA(pszOldOS, BUFSIZE, "Server " );
if ( lstrcmpi( TEXT("SERVERNT"), szProductType) == 0 )
StringCchCatA(pszOldOS, BUFSIZE, "Advanced Server " );
char szVer[20];
StringCchPrintfA(szVer, sizeof(szVer), "%d.%d ", osvi.dwMajorVersion, osvi.dwMinorVersion );
StringCchCatA(pszOldOS, BUFSIZE, szVer);
}

// Display service pack (if any) and build number.
char sp6[] = "Service Pack 6";
char szBuf[40];
if( osvi.dwMajorVersion == 4 &&
lstrcmpiA( osvi.szCSDVersion, sp6 ) == 0 )
{
HKEY hKey;
LONG lRet;

// Test for SP6 versus SP6a.
lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009"), 0, KEY_QUERY_VALUE, &hKey );
if( lRet == ERROR_SUCCESS )
{
StringCchPrintfA(szBuf, sizeof(szBuf), "Service Pack 6a (Build %d)", osvi.dwBuildNumber & 0xFFFF );
StringCchCatA(pszOldOS, BUFSIZE, szBuf);
}
else // Windows NT 4.0 prior to SP6a
{
StringCchPrintfA(szBuf, sizeof(szBuf), "%s (Build %d)", osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF);
StringCchCatA(pszOldOS, BUFSIZE, szBuf);
}
RegCloseKey( hKey );
}
else // not Windows NT 4.0
{
StringCchPrintfA(szBuf, sizeof(szBuf), "%s (Build %d)", osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF);
StringCchCatA(pszOldOS, BUFSIZE, szBuf);
}
}

return TRUE;
}

//int __cdecl _tmain()
int _tmain(int argc, _TCHAR* argv[])
{
TCHAR szOS[BUFSIZE];

if( GetOSDisplayString( szOS ) ){
_tprintf( TEXT("\n%s\n"), szOS );
}else{
char szOldOS[BUFSIZE] = {0};
if ( GetOldOSVer(szOldOS) ){
printf("\n%s\n", szOldOS);
}
}
}

   以上代码在Win98 SE/Windows Me/Windows NT4 Workstation/Win2000 Server/Windows XP/Win2003 Server Standard 32bit/Win7 Home Basic 64bit/Win8 Preview 32bit等32位/64位Windows系统中测试通过。Win95下因为是用VS2005编译的,无法执行,估计是调用API参数不匹配,导致执行出错,Windows 3.1当然也不行了,但Win95是有GetVersionEx这个函数的,用VC6写一个类似的函数就可以在Win95下执行。不过,用VC6要实现更多高级判别功能比较麻烦,因为必须自己定义一大堆的常量/结构以及API,好在Win 95用的人已经很少了。

  下面是用VC6写的简单测试代码,编译后可在Win95下正常运行:

// GetOSVer.cpp : Defines the entry point for the console application.
//

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

#ifndef SM_SERVERR2
#define SM_SERVERR2 89
#endif


int main(int argc, char* argv[])
{
OSVERSIONINFOEXA osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEXA));

// Try calling GetVersionEx using the OSVERSIONINFOEX structure.
// If that fails, try using the OSVERSIONINFO structure.
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA);
BOOL bOsVersionInfoEx = GetVersionExA ((OSVERSIONINFOA *) &osvi);
if( !bOsVersionInfoEx )
{
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
if (! GetVersionExA ( (OSVERSIONINFOA *) &osvi) )
{
printf("Unknow Windows? ");
return FALSE;
}
}

switch (osvi.dwPlatformId)
{
// Test for the Windows NT product family.
case VER_PLATFORM_WIN32_NT:
switch (osvi.dwMajorVersion)
{
case 5:
switch (osvi.dwMinorVersion)
{
case 0:
printf("Microsoft Windows 2000 ");
break;
case 1:
printf ("Microsoft Windows XP ");
break;
case 2:
if( GetSystemMetrics(SM_SERVERR2) ){
printf( "Microsoft Windows Server 2003 \"R2\" ");
}else{
printf ("Microsoft Windows Server 2003, ");
}
break;
}
break;
default:
if (osvi.dwMajorVersion <= 4){
printf ("Microsoft Windows NT ");
}
break;
}
// Test for the Windows Me/98/95.
case VER_PLATFORM_WIN32_WINDOWS:
if (osvi.dwMajorVersion == 4)
{
switch (osvi.dwMinorVersion)
{
case 0:
printf ("Microsoft Windows 95 ");
if (osvi.szCSDVersion[1]=='C' || osvi.szCSDVersion[1]=='B')
printf("OSR2 " );
break;
case 10:
printf ("Microsoft Windows 98 ");
if ( osvi.szCSDVersion[1]=='A' || osvi.szCSDVersion[1]=='B')
printf("SE " );
break;
case 90:
printf ("Microsoft Windows Millennium Edition ");
break;
}
}
break;
case VER_PLATFORM_WIN32s:
printf("Microsoft Win32s ");
break;
default:
printf("Unknow windows: Platform=%d, Version=%d.%d ", osvi.dwPlatformId, osvi.dwMajorVersion, osvi.dwMinorVersion);
break;
}

return 0;
}

  其实,如果不需要这么详细的版本信息,并且只需要处理NT内核的Windows,还有一个超简单的方法:查询注册表HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion下的几个键值就可以了,比如ProductName/CurrentVersion/CurrentBuildNumber/CSDVersion等等。不过,对Windows NT 4及3.51等老的NT系统有点麻烦,因为NT的注册表中没有ProductName!而只有 CurrentVersion/CurrentBuildNumber/CSDVersion等键值,所以需要自己判定。 对Windows 95/98/Me,则可以取HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion下的键值,比如ProductName/VersionNumber/SubVersionNumber等等。 

  转载请注明出处(http://dreamisx.blog.163.com/blog/static/1150048392012898257606/),谢谢~.~

  评论这张
 
阅读(7838)| 评论(1)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018