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