力战者
力战者,天酬之!

 

问题一:Windows SDK 8.1版本中的VersionHelper.h文件当中没有IsWindows10ORGreater,所以当你用IsWindows8Point1ORGreater判断出版本信息是Windows8.1以上的版本后,你就无法区分它到底是Win8.1还是Win10.

问题二:使用GetVersionEx这个API配合结构体OSVERSIONINFOEX这个方法获取版本信息,那么Win8以上的系统不论是Win8.1还是Win10都会被判定为主版本号为6,次版本号为2(即Win8的版本号)。

 

那么如何区分Win8.1和Win10?

使用如下未文档化API:

RtlGetNtVersionNumbers

 1 string GetNtVersionNumbers()
 2 {
 3     HMODULE hModNtdll = NULL;
 4     DWORD dwMajorVer, dwMinorVer, dwBuildNumber;
 5     OSVERSIONINFOEX lpVersionInformation;
 6 
 7     BOOL set = GetVersionExW((OSVERSIONINFO *)&lpVersionInformation);
 8 
 9     if ((lpVersionInformation.dwMajorVersion >= 6) && (lpVersionInformation.dwMinorVersion >= 2))
10     {
11         if (hModNtdll = ::LoadLibraryW(L"ntdll.dll"))
12         {
13             typedef void (WINAPI *pfRTLGETNTVERSIONNUMBERS)(DWORD*, DWORD*, DWORD*);
14             pfRTLGETNTVERSIONNUMBERS pfRtlGetNtVersionNumbers;
15             pfRtlGetNtVersionNumbers = (pfRTLGETNTVERSIONNUMBERS)::GetProcAddress(hModNtdll, "RtlGetNtVersionNumbers");
16             if (pfRtlGetNtVersionNumbers)
17             {
18                 pfRtlGetNtVersionNumbers(&dwMajorVer, &dwMinorVer, &dwBuildNumber);
19                 dwBuildNumber &= 0x0ffff;
20             }
21             ::FreeLibrary(hModNtdll);
22             hModNtdll = NULL;
23         }
24     }
25     string version = to_string(dwMajorVer) + "." + to_string(dwMinorVer) + "." + to_string(dwBuildNumber);
26     return version;
27 }

 

 

 

 获取计算机操作系统信息基本可以依靠一下几个函数来完成

CString strOperatingSystem(OSVERSIONINFOEX str,BOOL tes)
{
    // 系统信息
    CString pszOS,gszOS;
    if(tes)
        pszOS = _T("Windows");
    else
        pszOS = _T("Win");
    
    switch (str.dwPlatformId)
    {
    case VER_PLATFORM_WIN32_NT:
        if ( str.dwMajorVersion <= 4 )
            pszOS += _T("NT");
        else if ( str.dwMajorVersion == 5 )
        {
            if( str.dwMinorVersion == 0 )
                pszOS += _T("2000");
            else if( str.dwMinorVersion == 1 )
                pszOS += _T("XP");
            else if( str.dwMinorVersion == 2 )
            {
                if(str.wProductType==VER_NT_WORKSTATION )
                    pszOS += _T("XP_x64"); 
                else
                    pszOS += _T("2003");
            }
        }
        else if ( str.dwMajorVersion == 6 )
        {
            if( str.dwMinorVersion == 0 )
            {
                if(str.wProductType == VER_NT_WORKSTATION)
                    pszOS += _T("Vista");
                else
                    pszOS += _T("2008");
            }
            else if( str.dwMinorVersion == 1 )
            {
                if(str.wProductType == VER_NT_WORKSTATION)
                    pszOS += _T("7");
                else
                    pszOS += _T("2008R2");
            }
            else if( str.dwMinorVersion == 2 )
            {
                if(str.wProductType == VER_NT_WORKSTATION)
                    pszOS += _T("8");
                else
                    pszOS += _T("2012");
            }
            else if( str.dwMinorVersion == 3 )
            {
                if(str.wProductType == VER_NT_WORKSTATION)
                    pszOS += _T("8.1");
                else
                    pszOS += _T("2012R2");
            }
            else
                pszOS += _T("Null");
        }
        else if ( str.dwMajorVersion == 10 )
        {
            if( str.dwMinorVersion == 0 )
            {
                if(str.wProductType == VER_NT_WORKSTATION)
                    pszOS += _T("10");
                else
                    pszOS += _T("2016");
            }
        }
    }
    if(lstrlen(pszOS))
        gszOS.Format("%s SP%d",pszOS,str.wServicePackMajor);
    else
        gszOS = _T("未知操作系统");
    
    return gszOS;
}

// 读取系统位数
DWORD IsWow64()
{
    DWORD bIsWow = 32;
    BOOL bIsWow64 = FALSE;
    FARPROC fnIsWow64Process = GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "IsWow64Process");

    if(fnIsWow64Process)
        ((BOOL (WINAPI *)(HANDLE, PBOOL))fnIsWow64Process)(GetCurrentProcess(), &bIsWow64);

    if(bIsWow64)
        bIsWow = 64;
    else
        bIsWow = 32;
    
    return bIsWow;
}

BOOL GetNtVersionNumbers(DWORD&dwMajorVer, DWORD& dwMinorVer,DWORD& dwBuildNumber)
{
    BOOL bRet= FALSE;
    HMODULE hModNtdll= NULL;
    if (hModNtdll= ::LoadLibraryW(L"ntdll.dll"))
    {
        typedef void (WINAPI *pfRTLGETNTVERSIONNUMBERS)(DWORD*,DWORD*, DWORD*);
        pfRTLGETNTVERSIONNUMBERS pfRtlGetNtVersionNumbers;
        pfRtlGetNtVersionNumbers = (pfRTLGETNTVERSIONNUMBERS)::GetProcAddress(hModNtdll, "RtlGetNtVersionNumbers");
        if (pfRtlGetNtVersionNumbers)
        {
            pfRtlGetNtVersionNumbers(&dwMajorVer, &dwMinorVer,&dwBuildNumber);
            dwBuildNumber&= 0x0ffff;
            bRet = TRUE;
        }
        ::FreeLibrary(hModNtdll);
        hModNtdll = NULL;
    }

    return bRet;
}

// 获取系统版本号
BOOL g_GetVersionEx(OSVERSIONINFOEX &lpVersionInformation)
{
    ZeroMemory(&lpVersionInformation, sizeof(OSVERSIONINFOEX));
    lpVersionInformation.dwOSVersionInfoSize=sizeof(OSVERSIONINFOEX);
    BOOL set = GetVersionExA((OSVERSIONINFO *)&lpVersionInformation);

    if((lpVersionInformation.dwMajorVersion >= 6)&&(lpVersionInformation.dwMinorVersion >= 2))
    {
        DWORD dwMajorVer,dwMinorVer,dwBuildNumber;
        GetNtVersionNumbers(dwMajorVer,dwMinorVer,dwBuildNumber);
        lpVersionInformation.dwMajorVersion = dwMajorVer;
        lpVersionInformation.dwMinorVersion = dwMinorVer;
    }

    return set;
}

  void main()
  {
  // TODO: Add your control notification handler code here

  OSVERSIONINFOEX Log_OsVerInfoEx; // 系统版本信息

  g_GetVersionEx(Log_OsVerInfoEx);

  CString VerInfo;
  VerInfo.Format("%d.%d %s[%d位]",Log_OsVerInfoEx.dwMajorVersion,Log_OsVerInfoEx.dwMinorVersion,strOperatingSystem(Log_OsVerInfoEx,TRUE),IsWow64());

  SetDlgItemText(IDC_VERLNFOEX,VerInfo);

  }

 

 

posted on 2019-05-30 20:03  力战者  阅读(552)  评论(0编辑  收藏  举报