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

来源:互联网 发布:javascript timeout 编辑:程序博客网 时间:2024/05/18 01:10

之所以要写这篇文字,是在做一个安装程序时发现要探测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.

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

原创粉丝点击