得到Windows的版本及平台:Win32(x86), Win64 (x64)还是Win64(IA64)

之所以要写这篇文字,是在做一个安装程序时发现要探测Windows版本信息格外复杂,比如想根据平台不同可选择不同的安装文件,运行在x86平台 上的Windows 32bit OS只能安装32bit文件,而运行在x64平台上的Windows 64bit OS则可以选择安装32bit或64bit(x64),但是运行在x64平台上的Windows 32bit OS又只能安装32bit了,最后,运行在IA64平台上的Windows 64bit则可以选择安装32bit和64bit(IA64)。

首先,是一种常用的,在程序运行时判断操作系统是否为64bit的方法:调用kernel32.dll的IsWOW64Process函数。注意, 由于该函数是Windows XP SP2(Client),Windows Server 2003(Server)以后才被加入,所以,必须是动态Load该函数。

typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
LPFN_ISWOW64PROCESS fnIsWow64Process;

BOOL IsWow64()
{
    BOOL bIsWow64 = FALSE;
    fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress( GetModuleHandle(TEXT("kernel32")),"IsWow64Process");
    if (NULL != fnIsWow64Process)
    {
        if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64))
        { // handle error }
    }
    return bIsWow64;
}

这种方法可以迅速的判断当前进程是否运行在WOW64中,如果是,则当前平台为Windows 64bit,否则为Windows 32平台。问题是,这种方法依旧没法判断64bit的OS到底是x64还是IA64。

其次,Windows API在Windows XP以及其后的系统还加入了一个函数:GetNativeSystemInfo。配合上GetVersionEx,可以得出Windows系统的详细版本。

typedef enum eWindowsPlatform
{
    X86 = 0,
    X64 = 1,
    IA64 = 2
}
WindowsPlatform;

WindowsPlatform GetWindowsPlatform()
{
    OSVERSIONINFOEX osvi;
    SYSTEM_INFO si;
    PGNSI pGNSI;
    BOOL bOsVersionInfoEx;

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

    // Try calling GetVersionEx using the OSVERSIONINFOEX structure.
    // If that fails, try using the OSVERSIONINFO structure.

    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

    if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
    {
        osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
        if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
            return X86;
    }

    // Call GetNativeSystemInfo if supported
    // or GetSystemInfo otherwise.

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

    switch (osvi.dwPlatformId)
    {
        // Test for the Windows NT product family.

    case VER_PLATFORM_WIN32_NT:
        {
            if (si.wProcessorArchitecture ==
                PROCESSOR_ARCHITECTURE_IA64 )
                return IA64;
            else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
                return X64;
            else
                return X86;
        }
        break;

        // Test for the Windows Me/98/95.
    default:
        return X86;
    }
}

我在这里忽略掉了具体的Windows的版本信息,如果想判断具体是什么系统,只需要得到判断一下得到的OSVERSIONINFOEX 的dwMajorVersion以及dwMinorVersion即可。

dwMajorVersion:

Value
Meaning

4

The operating system is Windows NT 4.0, Windows Me, Windows 98, or Windows 95.

5

The operating system is Windows Server 2003 R2, Windows Server 2003, Windows XP, or Windows 2000.

6

The operating system is Windows Vista or Windows Server 2008.

dwMinorVersion:

Value
Meaning

0

The operating system is Windows Vista, Windows Server 2008, Windows 2000, Windows NT 4.0, or Windows 95.

1

The operating system is Windows XP.

2

The operating system is Windows Server 2003 R2, Windows Server 2003, or Windows XP Professional x64 Edition.

10

The operating system is Windows 98.

90

The operating system is Windows Me.

由此,对制作一个因为操作系统版本、平台不同而安装不同模块的安装程序,已经足够了。


// testWindows.cpp : 定义控制台应用程序的入口点。
//

//#include "stdafx.h"
//#include <Windows.h>
//#include <iostream>
//using namespace std;
//
//typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
//LPFN_ISWOW64PROCESS fnIsWow64Process;
//
//BOOL IsWow64()
//{
//    BOOL bIsWow64 = FALSE;
//    fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress( GetModuleHandle(TEXT("kernel32")),"IsWow64Process");
//    if (NULL != fnIsWow64Process)
//    {
//        if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64))
//        { // handle error }
//        }
//        return bIsWow64;
//    }
//}
//int _tmain(int argc, _TCHAR* argv[])
//{
//    bool ret = IsWow64();
//    cout<<ret<<endl;
//    return 0;
//}

#include <stdafx.h>
//#include "osInfor.h" //头文件,对下面几个函数的申明,略.
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
#include <iostream>
using namespace std;
#define BUFSIZE 100

//全局变量
BOOL g_bIsVista64 = FALSE;
BOOL g_bIsXP64    = FALSE;
//vista / NT
BOOL g_bVista = FALSE;
BOOL g_bNT32PlatForm = FALSE;
BOOL g_bIsWin2K = FALSE;

BOOL IsNT32Platform()
{
    return g_bNT32PlatForm;
}

BOOL IsVista()
{
    return g_bVista;
}

BOOL IsVista64()
{
    return g_bIsVista64;
}

BOOL IsXp64()
{
    return g_bIsXP64;
}

BOOL IsWin2K()
{
    return g_bIsWin2K;
}


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

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

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

    //Get Version Information
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
    if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
    {
        return 1;
    }

    // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise.
    pGNSI = (PGNSI) GetProcAddress(
        GetModuleHandle(TEXT("kernel32.dll")),
        "GetNativeSystemInfo");
    if(NULL != pGNSI)
    {
        pGNSI(&si);
    }
    else
    {
        GetSystemInfo(&si);
    }


    //vista / xp /2k(2k&#210;&#212;&#201;&#207;OS)
    if ( VER_PLATFORM_WIN32_NT==osvi.dwPlatformId &&
        osvi.dwMajorVersion > 4 )
    {
        g_bNT32PlatForm = TRUE;
        StringCchCopy(pszOS, BUFSIZE, TEXT("Microsoft "));

        //Vista
        if ( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0 )
        {
            g_bVista = TRUE;

            // Test for the specific product.
            if( osvi.wProductType == VER_NT_WORKSTATION )
            {
                StringCchCat(pszOS, BUFSIZE, TEXT("Windows Vista "));
            }
            else
            {
                StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2008 " ));
            }

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

            pGPI( 6, 0, 0, 0, &dwType);

            switch( dwType )
            {
            case /*PRODUCT_ULTIMATE*/1:
                StringCchCat(pszOS, BUFSIZE, TEXT("Ultimate Edition" ));
                break;
            case /*PRODUCT_HOME_PREMIUM*/2:
                StringCchCat(pszOS, BUFSIZE, TEXT("Home Premium Edition" ));
                break;
            case /*PRODUCT_HOME_BASIC*/3:
                StringCchCat(pszOS, BUFSIZE, TEXT("Home Basic Edition" ));
                break;
            case /*PRODUCT_ENTERPRISE*/4:
                StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition" ));
                break;
            case /*PRODUCT_BUSINESS*/5:
                StringCchCat(pszOS, BUFSIZE, TEXT("Business Edition" ));
                break;
            case /*PRODUCT_STARTER*/6:
                StringCchCat(pszOS, BUFSIZE, TEXT("Starter Edition" ));
                break;
            case /*PRODUCT_CLUSTER_SERVER*/7:
                StringCchCat(pszOS, BUFSIZE, TEXT("Cluster Server Edition" ));
                break;
            case /*PRODUCT_DATACENTER_SERVER*/8:
                StringCchCat(pszOS, BUFSIZE, TEXT("Datacenter Edition" ));
                break;
            case /*PRODUCT_DATACENTER_SERVER_CORE*/9:
                StringCchCat(pszOS, BUFSIZE, TEXT("Datacenter Edition (core installation)" ));
                break;
            case /*PRODUCT_ENTERPRISE_SERVER*/10:
                StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition" ));
                break;
            case /*PRODUCT_ENTERPRISE_SERVER_CORE*/11:
                StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition (core installation)" ));
                break;
            case /*PRODUCT_ENTERPRISE_SERVER_IA64*/12:
                StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition for Itanium-based Systems" ));
                break;
            case /*PRODUCT_SMALLBUSINESS_SERVER*/13:
                StringCchCat(pszOS, BUFSIZE, TEXT("Small Business Server" ));
                break;
            case /*PRODUCT_SMALLBUSINESS_SERVER_PREMIUM*/14:
                StringCchCat(pszOS, BUFSIZE, TEXT("Small Business Server Premium Edition" ));
                break;
            case /*PRODUCT_STANDARD_SERVER*/15:
                StringCchCat(pszOS, BUFSIZE, TEXT("Standard Edition" ));
                break;
            case /*PRODUCT_STANDARD_SERVER_CORE*/16:
                StringCchCat(pszOS, BUFSIZE, TEXT("Standard Edition (core installation)" ));
                break;
            case /*PRODUCT_WEB_SERVER*/17:
                StringCchCat(pszOS, BUFSIZE, TEXT("Web Server Edition" ));
                break;
            default:
                //printf("Product Type: %d/n", dwType);
                break;
            }
            if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 )
            {
                StringCchCat(pszOS, BUFSIZE, TEXT( ", 64-bit" ));
                g_bIsVista64 = TRUE;
            }
            else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL )
            {
                StringCchCat(pszOS, BUFSIZE, TEXT(", 32-bit"));
            }
            else
            {

            }
        }//Vista

        //server 2003
        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.wProductType == VER_NT_WORKSTATION &&
                si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
            {
                StringCchCat(pszOS, BUFSIZE, TEXT( "Windows XP Professional x64 Edition"));
                g_bIsXP64 = TRUE;
            }
            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" ));
                    }
                }
            }
        }//server2003

        //xp
        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" ));
        }

        //2k
        if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )
        {

            StringCchCat(pszOS, BUFSIZE, TEXT("Windows 2000 "));
            g_bIsWin2K = TRUE;

            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);

        return TRUE;
    }
    else//earlier windows
    {
        g_bNT32PlatForm = FALSE;
        //printf( "This sample does not support this version of Windows./n");
        return FALSE;
    }
}

typedef enum eWindowsPlatform
{
    X86 = 0,
    X64 = 1,
    IA64 = 2
}
WindowsPlatform;

WindowsPlatform GetWindowsPlatform()
{
    OSVERSIONINFOEX osvi;
    SYSTEM_INFO si;
    PGNSI pGNSI;
    BOOL bOsVersionInfoEx;

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

    // Try calling GetVersionEx using the OSVERSIONINFOEX structure.
    // If that fails, try using the OSVERSIONINFO structure.

    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

    if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
    {
        osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
        if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
            return X86;
    }

    // Call GetNativeSystemInfo if supported
    // or GetSystemInfo otherwise.

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

    switch (osvi.dwPlatformId)
    {
        // Test for the Windows NT product family.

    case VER_PLATFORM_WIN32_NT:
        {
            if (si.wProcessorArchitecture ==
                PROCESSOR_ARCHITECTURE_IA64 )
                return IA64;
            else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
                return X64;
            else
                return X86;
        }
        break;

        // Test for the Windows Me/98/95.
    default:
        return X86;
    }
}
int _tmain(int argc, _TCHAR* argv[])
{

    WindowsPlatform retWindows = GetWindowsPlatform();
    cout<<retWindows<<endl;
    return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值