windows平台下 c++獲取 系統版本 網卡 內存 CPU 硬盤 顯卡信息<轉>


GetsysInfo.h:

#ifndef _H_GETSYSINFO  
#define _H_GETSYSINFO  
  
  
#pragma once  
  
#include <afxtempl.h>  
  
class GetSysInfo  
{  
public:  
    GetSysInfo(void);  
    ~GetSysInfo(void);  
  
public:  
    /********獲取操作系統版本,Service pack版本、系統類型************/  
    void GetOSVersion(CString &strOSVersion,CString &strServiceVersion);  
    BOOL IsWow64();//判斷是否為64位操作系統  
  
    /***********獲取網卡數目和名字***********/  
    int  GetInterFaceCount();  
    void GetInterFaceName(CString &InterfaceName,int pNum);  
  
    /***獲取物理內存和虛擬內存大小***/  
    void GetMemoryInfo(CString &dwTotalPhys,CString &dwTotalVirtual);  
  
    /****獲取CPU名稱、內核數目、主頻*******/  
    void GetCpuInfo(CString &chProcessorName,CString &chProcessorType,DWORD &dwNum,DWORD &dwMaxClockSpeed);  
  
    /****獲取硬盤信息****/  
    void GetDiskInfo(DWORD &dwNum,CString chDriveInfo[]);  
  
    /****獲取顯卡信息*****/  
    void GetDisplayCardInfo(DWORD &dwNum,CString chCardName[]);  
private:  
    CStringList Interfaces;                       //保存所有網卡的名字  
    CList < DWORD, DWORD &>       Bandwidths;   //各網卡的帶寬  
    CList < DWORD, DWORD &>       TotalTraffics;    //各網卡的總流量  
};  
  
#endif  

 

Getsysinfo.cpp:

#include "StdAfx.h"  
#include "GetsysInfo.h"  
#include <atlbase.h>  
#include "float.h"  
#include "winperf.h"  
  
GetSysInfo::GetSysInfo(void)  
{  
}  
  
GetSysInfo::~GetSysInfo(void)  
{  
}  
  
void GetSysInfo::GetOSVersion(CString &strOSVersion,CString &strServiceVersion)  
{  
    CString str;  
    OSVERSIONINFOEX osvi;  
    SYSTEM_INFO si;  
    BOOL bOsVersionInfoEx;  
  
    ZeroMemory(&si, sizeof(SYSTEM_INFO));  
    ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));  
  
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);  
    if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )  
    {  
        osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);  
        GetVersionEx ( (OSVERSIONINFO *) &osvi);  
    }  
  
  
    GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),   
        "GetNativeSystemInfo");  
  
    GetSystemInfo(&si);  
    switch (osvi.dwPlatformId)  
    {  
    case VER_PLATFORM_WIN32_NT:  
        if ( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0 )  
        {  
            if( osvi.wProductType == VER_NT_WORKSTATION )  
            {  
                str.Format(_T("Windows Vista "));  
            }  
            else   
            {  
                str.Format(_T("Windows Server \"Longhorn\" "));  
            }  
        }  
        if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )  
        {  
            if( GetSystemMetrics(SM_SERVERR2) )  
            {  
                str.Format(_T("Microsoft Windows Server 2003 \"R2\" "));  
            }  
            else if( osvi.wProductType == VER_NT_WORKSTATION &&  
                si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)  
            {  
                str.Format(_T("Microsoft Windows XP Professional x64 Edition "));  
            }  
            else   
            {  
                str.Format(_T("Microsoft Windows Server 2003, "));  
            }  
        }  
  
        if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )  
        {  
            str.Format(_T("Microsoft Windows XP "));  
        }  
  
        if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )  
            str.Format(_T("Microsoft Windows 2000 "));  
  
        if ( osvi.dwMajorVersion <= 4 )  
        {  
            str.Format(_T("Microsoft Windows NT "));  
        }  
  
        // Test for specific product on Windows NT 4.0 SP6 and later.  
        if( bOsVersionInfoEx )  
        {  
  
            //將Service Pack 版本保存  
            strServiceVersion.Format(_T("Service Pack %d"),osvi.wServicePackMajor);  
  
            // Test for the workstation type.  
            if ( osvi.wProductType == VER_NT_WORKSTATION &&  
                si.wProcessorArchitecture!=PROCESSOR_ARCHITECTURE_AMD64)  
            {  
                if( osvi.dwMajorVersion == 4 )  
                    str = str + _T("Workstation 4.0");  
                else if( osvi.wSuiteMask & VER_SUITE_PERSONAL )  
                    str = str + _T("Home Edition");  
                else str = str + _T( "Professional");  
            }  
  
            // Test for the server type.  
            else if ( osvi.wProductType == VER_NT_SERVER ||   
                osvi.wProductType == VER_NT_DOMAIN_CONTROLLER )  
            {  
                if(osvi.dwMajorVersion==5 && osvi.dwMinorVersion==2)  
                {  
                    if ( si.wProcessorArchitecture ==  
                        PROCESSOR_ARCHITECTURE_IA64 )  
                    {  
                        if( osvi.wSuiteMask & VER_SUITE_DATACENTER )  
                            str = str + _T("Datacenter Edition for Itanium-based Systems");  
                        else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )  
                            str = str + _T("Enterprise Edition for Itanium-based Systems");  
                    }  
  
                    else if ( si.wProcessorArchitecture ==  
                        PROCESSOR_ARCHITECTURE_AMD64 )  
                    {  
                        if( osvi.wSuiteMask & VER_SUITE_DATACENTER )  
                            str = str + _T( "Datacenter x64 Edition ");  
                        else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )  
                            str = str + _T( "Enterprise x64 Edition ");  
                        else str = str + _T( "Standard x64 Edition ");  
                    }  
  
                    else  
                    {  
                        if( osvi.wSuiteMask & VER_SUITE_DATACENTER )  
                            str = str + _T( "Datacenter Edition ");  
                        else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )  
                            str = str + _T( "Enterprise Edition ");  
                        else if ( osvi.wSuiteMask & VER_SUITE_BLADE )  
                            str = str + _T( "Web Edition ");  
                        else str = str + _T( "Standard Edition ");  
                    }  
                }  
                else if(osvi.dwMajorVersion==5 && osvi.dwMinorVersion==0)  
                {  
                    if( osvi.wSuiteMask & VER_SUITE_DATACENTER )  
                        str = str + _T("Datacenter Server ");  
                    else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )  
                        str = str + _T( "Advanced Server ");  
                    else str = str + _T( "Server ");  
                }  
                else  // Windows NT 4.0   
                {  
                    if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )  
                        str = str + _T ("Server 4.0, Enterprise Edition ");  
                    else str = str + _T ( "Server 4.0 " );  
                }  
            }  
        }  
        // Test for specific product on Windows NT 4.0 SP5 and earlier  
        else    
        {  
            HKEY hKey;  
            TCHAR szProductType[256];  
            DWORD dwBufLen=256*sizeof(TCHAR);  
            LONG lRet;  
  
            lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,  
                _T("SYSTEM\\CurrentControlSet\\Control\\ProductOptions"), 0, KEY_QUERY_VALUE, &hKey );  
            if( lRet != ERROR_SUCCESS )  
                strOSVersion = str;  
                return;  
  
            lRet = RegQueryValueEx( hKey, TEXT("ProductType"),  
                NULL, NULL, (LPBYTE) szProductType, &dwBufLen);  
            RegCloseKey( hKey );  
  
            if( (lRet != ERROR_SUCCESS) ||  
                (dwBufLen > 256*sizeof(TCHAR)) )  
                strOSVersion = str;  
                return;  
  
            if ( lstrcmpi( TEXT("WINNT"), szProductType) == 0 )  
                str = str + _T( "Workstation ");  
            if ( lstrcmpi( TEXT("LANMANNT"), szProductType) == 0 )  
                str = str + _T( "Server " );  
            if ( lstrcmpi( TEXT("SERVERNT"), szProductType) == 0 )  
                str = str + _T( "Advanced Server ");  
            str.Format(_T( "%d.%d "), osvi.dwMajorVersion, osvi.dwMinorVersion );  
        }  
  
        // Display service pack (if any) and build number.  
  
        if( osvi.dwMajorVersion == 4 &&   
            lstrcmpi( osvi.szCSDVersion, TEXT("Service Pack 6") ) == 0 )  
        {   
            HKEY hKey;  
            LONG lRet;  
  
            // Test for SP6 versus SP6a.  
            lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,  
                _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009"), 0, KEY_QUERY_VALUE, &hKey );  
            if( lRet == ERROR_SUCCESS )  
                str.Format(_T( "Service Pack 6a (Build %d)\n"),   
                osvi.dwBuildNumber & 0xFFFF );           
            else // Windows NT 4.0 prior to SP6a  
            {  
                _tprintf( TEXT("%s (Build %d)\n"),  
                    osvi.szCSDVersion,  
                    osvi.dwBuildNumber & 0xFFFF);  
            }  
  
            RegCloseKey( hKey );  
        }  
        else // not Windows NT 4.0   
        {  
            _tprintf( TEXT("%s (Build %d)\n"),  
                osvi.szCSDVersion,  
                osvi.dwBuildNumber & 0xFFFF);  
        }  
  
        break;  
  
        // Test for the Windows Me/98/95.  
    case VER_PLATFORM_WIN32_WINDOWS:  
  
        if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)  
        {  
            str.Format(_T("Microsoft Windows 95 "));  
            if (osvi.szCSDVersion[1]=='C' || osvi.szCSDVersion[1]=='B')  
                str = str + _T("OSR2 ");  
        }   
  
        if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)  
        {  
            str.Format(_T("Microsoft Windows 98 "));  
            if ( osvi.szCSDVersion[1]=='A' || osvi.szCSDVersion[1]=='B')  
                str = str + _T("SE ");  
        }   
        if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)  
        {  
            str.Format(_T("Microsoft Windows Millennium Edition\n"));  
        }   
        break;  
  
    case VER_PLATFORM_WIN32s:  
        str.Format(_T("Microsoft Win32s\n"));  
        break;  
    default:  
        break;  
    }  
  
    strOSVersion = str;  
}  
  
BOOL GetSysInfo::IsWow64()   
{   
    typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);   
    LPFN_ISWOW64PROCESS fnIsWow64Process;   
    BOOL bIsWow64 = FALSE;   
    fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress( GetModuleHandle(_T("kernel32")),"IsWow64Process");   
    if (NULL != fnIsWow64Process)   
    {   
        fnIsWow64Process(GetCurrentProcess(),&bIsWow64);  
    }   
    return bIsWow64;   
}   
  
void GetSysInfo::GetCpuInfo(CString &chProcessorName,CString &chProcessorType,DWORD &dwNum,DWORD &dwMaxClockSpeed)  
{  
  
    CString strPath=_T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0");//注冊表子鍵路徑  
    CRegKey regkey;//定義注冊表類對象  
    LONG lResult;//LONG型變量-反應結果  
    lResult=regkey.Open(HKEY_LOCAL_MACHINE,LPCTSTR(strPath),KEY_ALL_ACCESS); //打開注冊表鍵  
    if (lResult!=ERROR_SUCCESS)  
    {  
        return;  
    }  
    WCHAR chCPUName[50] = {0};  
    DWORD dwSize=50;   
  
    //獲取ProcessorNameString字段值  
    if (ERROR_SUCCESS == regkey.QueryStringValue(_T("ProcessorNameString"),chCPUName,&dwSize))  
    {  
        chProcessorName = chCPUName;  
    }  
  
    //查詢CPU主頻  
    DWORD dwValue;  
    if (ERROR_SUCCESS == regkey.QueryDWORDValue(_T("~MHz"),dwValue))  
    {  
        dwMaxClockSpeed = dwValue;  
    }  
    regkey.Close();//關閉注冊表  
    //UpdateData(FALSE);  
  
    //獲取CPU核心數目  
    SYSTEM_INFO si;  
    memset(&si,0,sizeof(SYSTEM_INFO));  
    GetSystemInfo(&si);  
    dwNum = si.dwNumberOfProcessors;  
  
    switch (si.dwProcessorType)  
    {  
    case PROCESSOR_INTEL_386:  
        {  
            chProcessorType.Format(_T("Intel 386 processor"));  
        }  
        break;  
    case PROCESSOR_INTEL_486:  
        {  
            chProcessorType.Format(_T("Intel 486 Processor"));  
        }  
        break;  
    case PROCESSOR_INTEL_PENTIUM:  
        {  
            chProcessorType.Format(_T("Intel Pentium Processor"));  
        }  
        break;  
    case PROCESSOR_INTEL_IA64:  
        {  
            chProcessorType.Format(_T("Intel IA64 Processor"));  
        }  
        break;  
    case PROCESSOR_AMD_X8664:  
        {  
            chProcessorType.Format(_T("AMD X8664 Processor"));  
        }  
        break;  
    default:  
        chProcessorType.Format(_T("未知"));  
        break;  
    }  
  
    //GetDisplayName()  
}  
  
void  GetSysInfo::GetMemoryInfo(CString &dwTotalPhys,CString &dwTotalVirtual)   
{   
    //   TODO:     Add   extra   initialization   here   
    MEMORYSTATUS   Mem;   
    //   get   the   memory   status   
    GlobalMemoryStatus(&Mem);   
  
    DWORD dwSize = (DWORD)Mem.dwTotalPhys/(1024*1024);   
    DWORD dwVirtSize = (DWORD)Mem.dwTotalVirtual/(1024*1024);  
  
    dwTotalPhys.Format(_T("物理內存:%ld MB"),dwSize);   
    dwTotalVirtual.Format(_T("虛擬內存:%ld MB"),dwVirtSize);  
}  
  
int GetSysInfo::GetInterFaceCount()  
{  
    /*CGetNetData pNet; 
    DWORD pCount = pNet.GetNetworkInterfacesCount(); 
    return pCount;*/  
  
  
    try  
    {  
#define DEFAULT_BUFFER_SIZE 40960L  
  
        unsigned char *data = (unsigned char*)malloc(DEFAULT_BUFFER_SIZE);  
        DWORD type;  
        DWORD size = DEFAULT_BUFFER_SIZE;  
        DWORD ret;  
  
        char s_key[4096];  
        sprintf_s(s_key , 4096 , "510");  
        //RegQueryValueEx的固定調用格式          
        CString str(s_key);  
  
        //如果RegQueryValueEx函數執行失敗則進入循環  
        while((ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, str, 0, &type, data, &size)) != ERROR_SUCCESS)  
        {  
            Sleep(10);  
            //如果RegQueryValueEx的返回值為ERROR_MORE_DATA(申請的內存區data太小,不能容納RegQueryValueEx返回的數據)  
            if(ret == ERROR_MORE_DATA)   
            {  
                Sleep(10);  
                size += DEFAULT_BUFFER_SIZE;  
                data = (unsigned char*) realloc(data, size);//重新分配足夠大的內存  
  
                ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, str, 0, &type, data, &size);//重新執行RegQueryValueEx函數  
            }   
            //如果RegQueryValueEx返回值仍舊未成功則函數返回.....(注意內存泄露“free函數”~~~)。  
            //這個if保證了這個while只能進入一次~~~避免死循環  
            if(ret != ERROR_SUCCESS)  
            {  
                if (NULL != data)  
                {  
                    free(data);  
                    data = NULL;  
                }  
                return 0;//0個接口  
            }  
        }  
  
        //函數執行成功之后就是對返回的data內存中數據的解析了,這個建議去查看MSDN有關RegQueryValueEx函數參數數據結構的說明  
        //得到數據塊       
        PERF_DATA_BLOCK  *dataBlockPtr = (PERF_DATA_BLOCK *)data;  
        //得到第一個對象  
        PERF_OBJECT_TYPE *objectPtr = (PERF_OBJECT_TYPE *) ((BYTE *)dataBlockPtr + dataBlockPtr->HeaderLength);  
  
        for(int a=0 ; a<(int)dataBlockPtr->NumObjectTypes ; a++)   
        {  
            char nameBuffer[255] = {0};  
            if(objectPtr->ObjectNameTitleIndex == 510)   
            {  
                DWORD processIdOffset = ULONG_MAX;  
                PERF_COUNTER_DEFINITION *counterPtr =(PERF_COUNTER_DEFINITION *) ((BYTE *)objectPtr + objectPtr->HeaderLength);  
  
                for(int b=0 ; b<(int)objectPtr->NumCounters ; b++)   
                {  
                    if(counterPtr->CounterNameTitleIndex == 520)  
                        processIdOffset = counterPtr->CounterOffset;  
  
                    counterPtr =(PERF_COUNTER_DEFINITION *) ((BYTE *) counterPtr + counterPtr->ByteLength);  
                }  
  
                if(processIdOffset == ULONG_MAX) {  
                    if(data != NULL)  
                    {  
                        free(data);  
                        data = NULL;  
                    }  
                    return 0;  
                }  
  
                PERF_INSTANCE_DEFINITION *instancePtr =(PERF_INSTANCE_DEFINITION *)  ((BYTE *) objectPtr + objectPtr->DefinitionLength);  
  
                for(int b=0 ; b<objectPtr->NumInstances ; b++)   
                {  
                    wchar_t *namePtr = (wchar_t *) ((BYTE *)instancePtr + instancePtr->NameOffset);  
                    PERF_COUNTER_BLOCK *counterBlockPtr = (PERF_COUNTER_BLOCK *) ((BYTE *)instancePtr + instancePtr->ByteLength);  
          
                    char pName[256] = {0};  
                    WideCharToMultiByte(CP_ACP, 0, namePtr, -1, pName, sizeof(nameBuffer), 0, 0);  
  
                    DWORD bandwith = *((DWORD *) ((BYTE *)counterBlockPtr + processIdOffset));                
                    DWORD tottraff = 0;  
  
                    Interfaces.AddTail(CString(pName)); //各網卡的名稱  
                    Bandwidths.AddTail(bandwith);       //帶寬  
                    TotalTraffics.AddTail(tottraff);    // 流量初始化為0  
  
                    PERF_COUNTER_BLOCK  *pCtrBlk = (PERF_COUNTER_BLOCK *) ((BYTE *)instancePtr + instancePtr->ByteLength);  
  
                      
                    instancePtr = (PERF_INSTANCE_DEFINITION *) ((BYTE *)instancePtr + instancePtr->ByteLength + pCtrBlk->ByteLength);  
                }  
            }  
            objectPtr = (PERF_OBJECT_TYPE *) ((BYTE *)objectPtr + objectPtr->TotalByteLength);  
        }  
        if(data != NULL)  
        {  
            free(data);  
            data = NULL;  
        }  
    }  
    catch(...)  
    {  
        return 0;  
    }  
    return Interfaces.GetCount();  
}  
  
void GetSysInfo::GetInterFaceName(CString &InterfaceName,int pNum)  
{  
    /*CGetNetData pNet; 
    pNet.GetNetworkInterfaceName(&InterfaceName,pNum);*/  
  
    POSITION pos = Interfaces.FindIndex(pNum);  
    if(pos==NULL)  
        return ;  
  
    InterfaceName = Interfaces.GetAt(pos);  
    pos = Bandwidths.FindIndex(pNum);  
    if (pos == NULL)  
        return;  
    DWORD dwBandwidth = Bandwidths.GetAt(pos);  
  
    CString str;  
    str.Format(_T("%d"),dwBandwidth);  
  
    InterfaceName = InterfaceName + str;  
}  
  
void GetSysInfo::GetDiskInfo(DWORD &dwNum,CString chDriveInfo[])  
{  
    DWORD DiskCount = 0;  
  
    //利用GetLogicalDrives()函數可以獲取系統中邏輯驅動器的數量,函數返回的是一個32位無符號整型數據。  
    DWORD DiskInfo = GetLogicalDrives();  
  
    //通過循環操作查看每一位數據是否為1,如果為1則磁盤為真,如果為0則磁盤不存在。  
    while(DiskInfo)  
    {  
        //通過位運算的邏輯與操作,判斷是否為1  
        Sleep(10);  
        if(DiskInfo&1)  
        {  
            DiskCount++;  
        }  
        DiskInfo = DiskInfo >> 1;//通過位運算的右移操作保證每循環一次所檢查的位置向右移動一位。*/  
    }  
  
    if (dwNum < DiskCount)  
    {  
        return;//實際的磁盤數目大於dwNum  
    }  
    dwNum = DiskCount;//將磁盤分區數量保存  
  
  
    //-------------------------------------------------------------------//  
    //通過GetLogicalDriveStrings()函數獲取所有驅動器字符串信息長度  
    int DSLength = GetLogicalDriveStrings(0,NULL);  
  
      WCHAR* DStr = new WCHAR[DSLength];  
      memset(DStr,0,DSLength);  
  
      //通過GetLogicalDriveStrings將字符串信息復制到堆區數組中,其中保存了所有驅動器的信息。  
      GetLogicalDriveStrings(DSLength,DStr);  
  
      int DType;  
      int si=0;  
      BOOL fResult;  
      unsigned _int64 i64FreeBytesToCaller;  
      unsigned _int64 i64TotalBytes;  
      unsigned _int64 i64FreeBytes;  
  
      //讀取各驅動器信息,由於DStr內部數據格式是A:\NULLB:\NULLC:\NULL,所以DSLength/4可以獲得具體大循環范圍  
      for(int i=0;i<DSLength/4;++i)  
      {  
          Sleep(10);  
          CString strdriver = DStr+i*4;  
          CString strTmp,strTotalBytes,strFreeBytes;  
          DType = GetDriveType(strdriver);//GetDriveType函數,可以獲取驅動器類型,參數為驅動器的根目錄  
          switch (DType)  
          {  
          case DRIVE_FIXED:  
              {  
                  strTmp.Format(_T("本地磁盤"));  
              }  
            break;  
          case DRIVE_CDROM:  
              {  
                  strTmp.Format(_T("DVD驅動器"));  
              }  
              break;  
          case DRIVE_REMOVABLE:  
              {  
                  strTmp.Format(_T("可移動磁盤"));  
              }  
              break;  
          case DRIVE_REMOTE:  
              {  
                  strTmp.Format(_T("網絡磁盤"));  
              }  
              break;  
          case DRIVE_RAMDISK:  
              {  
                  strTmp.Format(_T("虛擬RAM磁盤"));  
              }  
              break;  
          case DRIVE_UNKNOWN:  
              {  
                  strTmp.Format(_T("虛擬RAM未知設備"));  
              }  
              break;  
          default:  
              strTmp.Format(_T("未知設備"));  
              break;  
          }  
  
          //GetDiskFreeSpaceEx函數,可以獲取驅動器磁盤的空間狀態,函數返回的是個BOOL類型數據  
          fResult = GetDiskFreeSpaceEx (strdriver,  
              (PULARGE_INTEGER)&i64FreeBytesToCaller,  
              (PULARGE_INTEGER)&i64TotalBytes,  
              (PULARGE_INTEGER)&i64FreeBytes);  
                
          if(fResult)  
          {  
              strTotalBytes.Format(_T("磁盤總容量%fMB"),(float)i64TotalBytes/1024/1024);  
              strFreeBytes.Format(_T("磁盤剩余空間%fMB"),(float)i64FreeBytesToCaller/1024/1024);  
          }  
          else  
          {  
              strTotalBytes.Format(_T(""));  
              strFreeBytes.Format(_T(""));  
          }  
          chDriveInfo[i] = strTmp + _T("(") + strdriver + _T("):") + strTotalBytes + strFreeBytes;  
          si+=4;  
      }  
}  
  
void GetSysInfo::GetDisplayCardInfo(DWORD &dwNum,CString chCardName[])  
{  
    HKEY keyServ;  
    HKEY keyEnum;  
    HKEY key;  
    HKEY key2;  
    LONG lResult;//LONG型變量-保存函數返回值  
  
    //查詢"SYSTEM\\CurrentControlSet\\Services"下的所有子鍵保存到keyServ  
    lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Services"),0,KEY_READ,&keyServ);  
    if (ERROR_SUCCESS != lResult)  
        return;  
  
  
    //查詢"SYSTEM\\CurrentControlSet\\Enum"下的所有子鍵保存到keyEnum  
    lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Enum"),0,KEY_READ,&keyEnum);  
    if (ERROR_SUCCESS != lResult)  
        return;  
  
    int i = 0,count = 0;  
    DWORD size = 0,type = 0;  
    for (;;++i)  
    {  
        Sleep(5);  
        size = 512;  
        TCHAR name[512] = {0};//保存keyServ下各子項的字段名稱  
  
        //逐個枚舉keyServ下的各子項字段保存到name中  
        lResult = RegEnumKeyEx(keyServ,i,name,&size,NULL,NULL,NULL,NULL);  
  
        //要讀取的子項不存在,即keyServ的子項全部遍歷完時跳出循環  
        if(lResult == ERROR_NO_MORE_ITEMS)  
            break;  
  
        //打開keyServ的子項字段為name所標識的字段的值保存到key  
        lResult = RegOpenKeyEx(keyServ,name,0,KEY_READ,&key);  
        if (lResult != ERROR_SUCCESS)  
        {  
            RegCloseKey(keyServ);  
            return;  
        }  
          
  
        size = 512;  
        //查詢key下的字段為Group的子鍵字段名保存到name  
        lResult = RegQueryValueEx(key,TEXT("Group"),0,&type,(LPBYTE)name,&size);  
        if(lResult == ERROR_FILE_NOT_FOUND)  
        {  
            //?鍵不存在  
            RegCloseKey(key);  
            continue;  
        };  
  
  
  
        //如果查詢到的name不是Video則說明該鍵不是顯卡驅動項  
        if(_tcscmp(TEXT("Video"),name)!=0)  
        {  
            RegCloseKey(key);  
            continue;     //返回for循環  
        };  
          
        //如果程序繼續往下執行的話說明已經查到了有關顯卡的信息,所以在下面的代碼執行完之后要break第一個for循環,函數返回  
        lResult = RegOpenKeyEx(key,TEXT("Enum"),0,KEY_READ,&key2);  
        RegCloseKey(key);  
        key = key2;  
        size = sizeof(count);  
        lResult = RegQueryValueEx(key,TEXT("Count"),0,&type,(LPBYTE)&count,&size);//查詢Count字段(顯卡數目)  
  
        dwNum = count;//保存顯卡數目  
        for(int j=0;j <count;++j)  
        {  
            TCHAR sz[512] = {0};  
            TCHAR name[64] = {0};  
            wsprintf(name,TEXT("%d"),j);  
            size = sizeof(sz);  
            lResult  = RegQueryValueEx(key,name,0,&type,(LPBYTE)sz,&size);  
  
  
            lResult = RegOpenKeyEx(keyEnum,sz,0,KEY_READ,&key2);  
            if (ERROR_SUCCESS)  
            {  
                RegCloseKey(keyEnum);  
                return;  
            }  
              
  
            size = sizeof(sz);  
            lResult = RegQueryValueEx(key2,TEXT("FriendlyName"),0,&type,(LPBYTE)sz,&size);  
            if(lResult == ERROR_FILE_NOT_FOUND)  
            {  
                size = sizeof(sz);  
                lResult = RegQueryValueEx(key2,TEXT("DeviceDesc"),0,&type,(LPBYTE)sz,&size);  
                chCardName[j] = sz;//保存顯卡名稱  
            };  
            RegCloseKey(key2);  
            key2 = NULL;  
        };  
        RegCloseKey(key);  
        key = NULL;  
        break;  
    }  
}  

測試Test_cpu.cpp:

// Test_cpu.cpp : 定義控制台應用程序的入口點。  
//  
  
#include "stdafx.h"  
// Test_cpu.cpp : 定義控制台應用程序的入口點。  
//  
  
//=====================================================================================  
/*                 CPUID指令是intel IA32架構下獲得CPU信息的匯編指令, 
                   可以得到CPU類型,型號,制造商信息,商標信息,序列號, 
                   緩存等一系列CPU相關的東西。 
*/  
#include "stdafx.h"  
//#include <windows.h>  
#include "GetsysInfo.h"  
#include <iostream>  
#include <string>  
  
using namespace std;  
  
  
//用來存儲eax,ebx,ecx,edx四個寄存器的信息  
DWORD deax;  
DWORD debx;  
DWORD decx;  
DWORD dedx;  
  
void ExeCPUID(DWORD veax)  //初始化CPU  
{  
__asm  
{  
    mov eax,veax  
    cpuid  
    mov deax,eax  
    mov debx,ebx  
    mov decx,ecx  
    mov dedx,edx  
}  
}  
  
/*    在Intel Pentium以上級別的CPU中,有一個稱為“時間戳(Time Stamp)”的部件, 
    它以64位無符號整型數的格式,記錄了自CPU上電以來所經過的時鍾周期數。 
    由於目前的CPU主頻都非常高,因此這個部件可以達到納秒級的計時精度。 
    這個精確性是上述兩種方法所無法比擬的。 
    在Pentium以上的CPU中,提供了一條機器指令RDTSC(Read Time Stamp Counter) 
    來讀取這個時間戳的數字,並將其保存在EDX:EAX寄存器對中 
*/  
long GetCPUFreq()       //獲取CPU頻率,單位: MHZ  
{  
    int start,over;  
    _asm   
    {  
        RDTSC  
        mov start,eax  
    }  
    Sleep(50);  
    _asm   
    {  
        RDTSC  
        mov over,eax  
    }  
    return (over-start)/50000;  
}  
  
  
  
/*   把eax = 0作為輸入參數,可以得到CPU的制造商信息。 
     cpuid指令執行以后,會返回一個12字符的制造商信息, 
     前四個字符的ASC碼按低位到高位放在ebx,中間四個放在edx,最后四個字符放在ecx。 
*/  
string GetManID()   //獲取制造商信息  
{  
    char ID[25];          
    memset(ID,0,sizeof(ID));  
      
    ExeCPUID(0);          //初始化  
    memcpy(ID+0,&debx,4); //制造商信息復制到數組  
    memcpy(ID+4,&dedx,4);  
    memcpy(ID+8,&decx,4);  
      
    return string(ID);  
}  
  
  
/*  在我的電腦上點擊右鍵,選擇屬性,可以在窗口的下面看到一條CPU的信息, 
    這就是CPU的商標字符串。CPU的商標字符串也是通過cpuid得到的。 
    由於商標的字符串很長(48個字符),所以不能在一次cpuid指令執行時全部得到, 
    所以intel把它分成了3個操作,eax的輸入參數分別是0x80000002,0x80000003,0x80000004, 
    每次返回的16個字符,按照從低位到高位的順序依次放在eax, ebx, ecx, edx。 
    因此,可以用循環的方式,每次執行完以后保存結果,然后執行下一次cpuid。 
*/  
string GetCPUType()  
{  
    const DWORD id = 0x80000002; //從0x80000002開始,到0x80000004結束  
    char CPUType[49];//用來存儲CPU型號信息  
    memset(CPUType,0,sizeof(CPUType));//初始化數組  
      
    for(DWORD t = 0 ; t < 3 ; t++ )  
    {  
        ExeCPUID(id+t);  
        //每次循環結束,保存信息到數組  
        memcpy(CPUType+16*t+ 0,&deax,4);  
        memcpy(CPUType+16*t+ 4,&debx,4);  
        memcpy(CPUType+16*t+ 8,&decx,4);  
        memcpy(CPUType+16*t+12,&dedx,4);  
    }  
      
    return string(CPUType);  
}  
  
void main()   
{   
    cout<<"本機CPU信息如下:"<<endl;  
    cout<<"CPU 主 頻: "<<GetCPUFreq()<<" MHZ"<<endl;  
    cout<<"CPU 制造商: "<<GetManID()<<endl;  
    cout<<"CPU 型 號: "<<GetCPUType()<<endl;  
   // cin.get();  
  
  
    cout<<"------------------------------------------"<<endl;  
    DWORD dwnum = 0 ;  
    CString info[20];  
    CString totalmemery,totalvirtual;  
    GetSysInfo* sys = new GetSysInfo();  
    //sys->GetDiskInfo(dwnum,info);  
    //sys->GetMemoryInfo(totalmemery,totalvirtual);  
    //wstring total = totalmemery.GetBuffer(0);  
    //wstring processname = chProcessorName.GetBuffer(0);  
    //wcout<<total<<endl;  
    //wcout<<totalvirtual.GetBuffer(0)<<endl;  
  
  
  
    CString chProcessorName;  
    CString chProcessorType;  
    DWORD dwNum;  
    DWORD dwMaxClockSpeed;  
    sys->GetCpuInfo( chProcessorName, chProcessorType, dwNum, dwMaxClockSpeed);  
    //wstring processname = chProcessorName.GetBuffer(0);//unicode要使用對應版本的函數  
    wcout<<chProcessorName.GetBuffer(0)<<endl;  
    wcout<<chProcessorType.GetBuffer(0)<<endl;  
    delete sys;  
  
    getchar();  
  
}  

效果:

 

原地:http://blog.csdn.net/whatday/article/details/44978593


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM