C/C++经过WMI和系统API函数获取获取系统硬件(cpu,内存,显卡,网卡)配置信息

2020年02月05日 阅读数:676
这篇文章主要向大家介绍C/C++经过WMI和系统API函数获取获取系统硬件(cpu,内存,显卡,网卡)配置信息,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

 前段时间因为项目须要,要求作一个服务器的实时性能监控(CPU、内存、网络利用率等)和读取服务器的硬件配置参数的接口供项目组使用,就是一个相似于鲁大师之类的东东吧...程序员

     固然第一想法确定是利用Windows提供的系统标准API函数来完成所需的功能,固然这也应该是当前最理想最有效率的选择了。可是若是你对API编程不是很熟练的话...那就至关蛋疼了!你知道用API能够作到可是不知道用哪一个API,好啊,能够查MSDN。问题是你连API名字都不知道...固然,若是大家公司容许大家上国内局域网的话那就好办多了,由于有无数强大的网友会帮你找到答案。使用API编程的另外一个问题是若是你仍旧对API不熟悉的话调用起来至关困难、很不顺手。编程

    还有一种方案就是--->“强大”的WMI,.net平台的程序员可能对这个比较熟悉,WMI即windows管理规范。经过它能够访问、配置、管理和监视几乎全部的Windows资源。固然对于程序员而言在WMI体系结构中咱们最须要关心的就是WMI提供的程序和接口。windows

    WMI提供程序在WMI和托管资源之间扮演着中间方的角色。提供程序表明使用者应用程序和脚本从WMI托管资源请求信息,并发送指令到WMI托管资源。
下面是咱们利用WMI编程常常要用到的WMI内置提供程序清单,以供编程参考。数组

1.Active Directory提供程序  
连接库文件:dsprov.dll  
命名空间:root\directory\ldap  
做用:将Active Directory 对象映射到 WMI。 安全

2.事件日志提供程序  
连接库文件:ntevt.dll  
命名空间:root\cimv2  
做用:管理 Windows 事件日志,例如,读取、备份、清除、复制、删除、监视、重命名、压缩、解压缩和更改事件日志设置。 服务器

3.注册表提供程序  
连接库文件:stdprov.dll  
命名空间:root\default  
做用:读取、写入、枚举、监视、建立、删除注册表项和值。 网络

4.Win32 提供程序  
连接库文件:cimwin32.dll  
命名空间:root\cimv2  
做用:提供关于计算机、磁盘、外围设备、文件、文件夹、文件系统、网络组件、操做系统、打印机、进程、安全性、服务、共享、SAM 用户及组,以及更多资源的信息。 数据结构

5.Windows 安装程序提供程序  
连接库文件:msiprov.dll  
命名空间:root\cimv2  
做用:提供对已安装软件信息的访问。并发

  以上能够看出WMI中的类被分组到不一样的命名空间中,因此咱们在调用相应的程序库时要注意引入对应的命名空间~~~咱们今天用到的库就是cimwin32.dll库(第4个)。
好,废话到此为止,还有不懂的本身下去慢慢研究:如今看代码...ide

 

1、基于API方式的实现代码,简单的对部分API函数的封装:

     一、GetSysInfo.h文件

[cpp]  view plain copy
  1. pragma once  
  2.   
  3.      #include <afxtempl.h>  
  4.   
  5.      class GetSysInfo  
  6.      {  
  7.      public:  
  8.     GetSysInfo(void);  
  9.     ~GetSysInfo(void);  
  10.   
  11.      public:  
  12.     /********获取操做系统版本,Service pack版本、系统类型************/  
  13.     void GetOSVersion(CString &strOSVersion,CString &strServiceVersion);  
  14.     BOOL IsWow64();//判断是否为64位操做系统  
  15.   
  16.     /***********获取网卡数目和名字***********/  
  17.     int  GetInterFaceCount();  
  18.     void GetInterFaceName(CString &InterfaceName,int pNum);  
  19.   
  20.     /***获取物理内存和虚拟内存大小***/  
  21.     void GetMemoryInfo(CString &dwTotalPhys,CString &dwTotalVirtual);  
  22.   
  23.     /****获取CPU名称、内核数目、主频*******/  
  24.     void GetCpuInfo(CString &chProcessorName,CString &chProcessorType,DWORD &dwNum,DWORD &dwMaxClockSpeed);  
  25.   
  26.     /****获取硬盘信息****/  
  27.     void GetDiskInfo(DWORD &dwNum,CString chDriveInfo[]);  
  28.   
  29.     /****获取显卡信息*****/  
  30.     void GetDisplayCardInfo(DWORD &dwNum,CString chCardName[]);  
  31.      private:  
  32.     CStringList Interfaces;                       //保存全部网卡的名字  
  33.     CList < DWORDDWORD &>       Bandwidths;   //各网卡的带宽  
  34.     CList < DWORDDWORD &>       TotalTraffics;    //各网卡的总流量  
  35.      };  


2.GetSysInfo.cpp文件

 

[cpp]  view plain copy
  1. #include "StdAfx.h"  
  2. #include "GetSysInfo.h"  
  3. #include "float.h"  
  4. #include "winperf.h"  
  5.   
  6. GetSysInfo::GetSysInfo(void)  
  7. {  
  8. }  
  9.   
  10. GetSysInfo::~GetSysInfo(void)  
  11. {  
  12. }  
  13.   
  14. void GetSysInfo::GetOSVersion(CString &strOSVersion,CString &strServiceVersion)  
  15. {  
  16.     CString str;  
  17.     OSVERSIONINFOEX osvi;  
  18.     SYSTEM_INFO si;  
  19.     BOOL bOsVersionInfoEx;  
  20.   
  21.     ZeroMemory(&si, sizeof(SYSTEM_INFO));  
  22.     ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));  
  23.   
  24.     osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);  
  25.     if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )  
  26.     {  
  27.         osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);  
  28.         GetVersionEx ( (OSVERSIONINFO *) &osvi);  
  29.     }  
  30.   
  31.   
  32.     GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),   
  33.         "GetNativeSystemInfo");  
  34.   
  35.     GetSystemInfo(&si);  
  36.     switch (osvi.dwPlatformId)  
  37.     {  
  38.     case VER_PLATFORM_WIN32_NT:  
  39.         if ( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0 )  
  40.         {  
  41.             if( osvi.wProductType == VER_NT_WORKSTATION )  
  42.             {  
  43.                 str.Format(_T("Windows Vista "));  
  44.             }  
  45.             else   
  46.             {  
  47.                 str.Format(_T("Windows Server \"Longhorn\" "));  
  48.             }  
  49.         }  
  50.         if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )  
  51.         {  
  52.             if( GetSystemMetrics(SM_SERVERR2) )  
  53.             {  
  54.                 str.Format(_T("Microsoft Windows Server 2003 \"R2\" "));  
  55.             }  
  56.             else if( osvi.wProductType == VER_NT_WORKSTATION &&  
  57.                 si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)  
  58.             {  
  59.                 str.Format(_T("Microsoft Windows XP Professional x64 Edition "));  
  60.             }  
  61.             else   
  62.             {  
  63.                 str.Format(_T("Microsoft Windows Server 2003, "));  
  64.             }  
  65.         }  
  66.   
  67.         if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )  
  68.         {  
  69.             str.Format(_T("Microsoft Windows XP "));  
  70.         }  
  71.   
  72.         if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )  
  73.             str.Format(_T("Microsoft Windows 2000 "));  
  74.   
  75.         if ( osvi.dwMajorVersion <= 4 )  
  76.         {  
  77.             str.Format(_T("Microsoft Windows NT "));  
  78.         }  
  79.   
  80.         // Test for specific product on Windows NT 4.0 SP6 and later.  
  81.         if( bOsVersionInfoEx )  
  82.         {  
  83.   
  84.             //将Service Pack 版本保存  
  85.             strServiceVersion.Format(_T("Service Pack %d"),osvi.wServicePackMajor);  
  86.   
  87.             // Test for the workstation type.  
  88.             if ( osvi.wProductType == VER_NT_WORKSTATION &&  
  89.                 si.wProcessorArchitecture!=PROCESSOR_ARCHITECTURE_AMD64)  
  90.             {  
  91.                 if( osvi.dwMajorVersion == 4 )  
  92.                     str = str + _T("Workstation 4.0");  
  93.                 else if( osvi.wSuiteMask & VER_SUITE_PERSONAL )  
  94.                     str = str + _T("Home Edition");  
  95.                 else str = str + _T( "Professional");  
  96.             }  
  97.   
  98.             // Test for the server type.  
  99.             else if ( osvi.wProductType == VER_NT_SERVER ||   
  100.                 osvi.wProductType == VER_NT_DOMAIN_CONTROLLER )  
  101.             {  
  102.                 if(osvi.dwMajorVersion==5 && osvi.dwMinorVersion==2)  
  103.                 {  
  104.                     if ( si.wProcessorArchitecture ==  
  105.                         PROCESSOR_ARCHITECTURE_IA64 )  
  106.                     {  
  107.                         if( osvi.wSuiteMask & VER_SUITE_DATACENTER )  
  108.                             str = str + _T("Datacenter Edition for Itanium-based Systems");  
  109.                         else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )  
  110.                             str = str + _T("Enterprise Edition for Itanium-based Systems");  
  111.                     }  
  112.   
  113.                     else if ( si.wProcessorArchitecture ==  
  114.                         PROCESSOR_ARCHITECTURE_AMD64 )  
  115.                     {  
  116.                         if( osvi.wSuiteMask & VER_SUITE_DATACENTER )  
  117.                             str = str + _T( "Datacenter x64 Edition ");  
  118.                         else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )  
  119.                             str = str + _T( "Enterprise x64 Edition ");  
  120.                         else str = str + _T( "Standard x64 Edition ");  
  121.                     }  
  122.   
  123.                     else  
  124.                     {  
  125.                         if( osvi.wSuiteMask & VER_SUITE_DATACENTER )  
  126.                             str = str + _T( "Datacenter Edition ");  
  127.                         else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )  
  128.                             str = str + _T( "Enterprise Edition ");  
  129.                         else if ( osvi.wSuiteMask & VER_SUITE_BLADE )  
  130.                             str = str + _T( "Web Edition ");  
  131.                         else str = str + _T( "Standard Edition ");  
  132.                     }  
  133.                 }  
  134.                 else if(osvi.dwMajorVersion==5 && osvi.dwMinorVersion==0)  
  135.                 {  
  136.                     if( osvi.wSuiteMask & VER_SUITE_DATACENTER )  
  137.                         str = str + _T("Datacenter Server ");  
  138.                     else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )  
  139.                         str = str + _T( "Advanced Server ");  
  140.                     else str = str + _T( "Server ");  
  141.                 }  
  142.                 else  // Windows NT 4.0   
  143.                 {  
  144.                     if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )  
  145.                         str = str + _T ("Server 4.0, Enterprise Edition ");  
  146.                     else str = str + _T ( "Server 4.0 " );  
  147.                 }  
  148.             }  
  149.         }  
  150.         // Test for specific product on Windows NT 4.0 SP5 and earlier  
  151.         else    
  152.         {  
  153.             HKEY hKey;  
  154.             TCHAR szProductType[256];  
  155.             DWORD dwBufLen=256*sizeof(TCHAR);  
  156.             LONG lRet;  
  157.   
  158.             lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,  
  159.                 _T("SYSTEM\\CurrentControlSet\\Control\\ProductOptions"), 0, KEY_QUERY_VALUE, &hKey );  
  160.             if( lRet != ERROR_SUCCESS )  
  161.                 strOSVersion = str;  
  162.                 return;  
  163.   
  164.             lRet = RegQueryValueEx( hKey, TEXT("ProductType"),  
  165.                 NULL, NULL, (LPBYTE) szProductType, &dwBufLen);  
  166.             RegCloseKey( hKey );  
  167.   
  168.             if( (lRet != ERROR_SUCCESS) ||  
  169.                 (dwBufLen > 256*sizeof(TCHAR)) )  
  170.                 strOSVersion = str;  
  171.                 return;  
  172.   
  173.             if ( lstrcmpi( TEXT("WINNT"), szProductType) == 0 )  
  174.                 str = str + _T( "Workstation ");  
  175.             if ( lstrcmpi( TEXT("LANMANNT"), szProductType) == 0 )  
  176.                 str = str + _T( "Server " );  
  177.             if ( lstrcmpi( TEXT("SERVERNT"), szProductType) == 0 )  
  178.                 str = str + _T( "Advanced Server ");  
  179.             str.Format(_T( "%d.%d "), osvi.dwMajorVersion, osvi.dwMinorVersion );  
  180.         }  
  181.   
  182.         // Display service pack (if any) and build number.  
  183.   
  184.         if( osvi.dwMajorVersion == 4 &&   
  185.             lstrcmpi( osvi.szCSDVersion, TEXT("Service Pack 6") ) == 0 )  
  186.         {   
  187.             HKEY hKey;  
  188.             LONG lRet;  
  189.   
  190.             // Test for SP6 versus SP6a.  
  191.             lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,  
  192.                 _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009"), 0, KEY_QUERY_VALUE, &hKey );  
  193.             if( lRet == ERROR_SUCCESS )  
  194.                 str.Format(_T( "Service Pack 6a (Build %d)\n"),   
  195.                 osvi.dwBuildNumber & 0xFFFF );           
  196.             else // Windows NT 4.0 prior to SP6a  
  197.             {  
  198.                 _tprintf( TEXT("%s (Build %d)\n"),  
  199.                     osvi.szCSDVersion,  
  200.                     osvi.dwBuildNumber & 0xFFFF);  
  201.             }  
  202.   
  203.             RegCloseKey( hKey );  
  204.         }  
  205.         else // not Windows NT 4.0   
  206.         {  
  207.             _tprintf( TEXT("%s (Build %d)\n"),  
  208.                 osvi.szCSDVersion,  
  209.                 osvi.dwBuildNumber & 0xFFFF);  
  210.         }  
  211.   
  212.         break;  
  213.   
  214.         // Test for the Windows Me/98/95.  
  215.     case VER_PLATFORM_WIN32_WINDOWS:  
  216.   
  217.         if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)  
  218.         {  
  219.             str.Format(_T("Microsoft Windows 95 "));  
  220.             if (osvi.szCSDVersion[1]=='C' || osvi.szCSDVersion[1]=='B')  
  221.                 str = str + _T("OSR2 ");  
  222.         }   
  223.   
  224.         if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)  
  225.         {  
  226.             str.Format(_T("Microsoft Windows 98 "));  
  227.             if ( osvi.szCSDVersion[1]=='A' || osvi.szCSDVersion[1]=='B')  
  228.                 str = str + _T("SE ");  
  229.         }   
  230.         if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)  
  231.         {  
  232.             str.Format(_T("Microsoft Windows Millennium Edition\n"));  
  233.         }   
  234.         break;  
  235.   
  236.     case VER_PLATFORM_WIN32s:  
  237.         str.Format(_T("Microsoft Win32s\n"));  
  238.         break;  
  239.     default:  
  240.         break;  
  241.     }  
  242.   
  243.     strOSVersion = str;  
  244. }  
  245.   
  246. BOOL GetSysInfo::IsWow64()   
  247. {   
  248.     typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLEPBOOL);   
  249.     LPFN_ISWOW64PROCESS fnIsWow64Process;   
  250.     BOOL bIsWow64 = FALSE;   
  251.     fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress( GetModuleHandle(_T("kernel32")),"IsWow64Process");   
  252.     if (NULL != fnIsWow64Process)   
  253.     {   
  254.         fnIsWow64Process(GetCurrentProcess(),&bIsWow64);  
  255.     }   
  256.     return bIsWow64;   
  257. }   
  258.   
  259. void GetSysInfo::GetCpuInfo(CString &chProcessorName,CString &chProcessorType,DWORD &dwNum,DWORD &dwMaxClockSpeed)  
  260. {  
  261.   
  262.     CString strPath=_T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0");//注册表子键路径  
  263.     CRegKey regkey;//定义注册表类对象  
  264.     LONG lResult;//LONG型变量-反应结果  
  265.     lResult=regkey.Open(HKEY_LOCAL_MACHINE,LPCTSTR(strPath),KEY_ALL_ACCESS); //打开注册表键  
  266.     if (lResult!=ERROR_SUCCESS)  
  267.     {  
  268.         return;  
  269.     }  
  270.     WCHAR chCPUName[50] = {0};  
  271.     DWORD dwSize=50;   
  272.   
  273.     //获取ProcessorNameString字段值  
  274.     if (ERROR_SUCCESS == regkey.QueryStringValue(_T("ProcessorNameString"),chCPUName,&dwSize))  
  275.     {  
  276.         chProcessorName = chCPUName;  
  277.     }  
  278.   
  279.     //查询CPU主频  
  280.     DWORD dwValue;  
  281.     if (ERROR_SUCCESS == regkey.QueryDWORDValue(_T("~MHz"),dwValue))  
  282.     {  
  283.         dwMaxClockSpeed = dwValue;  
  284.     }  
  285.     regkey.Close();//关闭注册表  
  286.     //UpdateData(FALSE);  
  287.   
  288.     //获取CPU核心数目  
  289.     SYSTEM_INFO si;  
  290.     memset(&si,0,sizeof(SYSTEM_INFO));  
  291.     GetSystemInfo(&si);  
  292.     dwNum = si.dwNumberOfProcessors;  
  293.   
  294.     switch (si.dwProcessorType)  
  295.     {  
  296.     case PROCESSOR_INTEL_386:  
  297.         {  
  298.             chProcessorType.Format(_T("Intel 386 processor"));  
  299.         }  
  300.         break;  
  301.     case PROCESSOR_INTEL_486:  
  302.         {  
  303.             chProcessorType.Format(_T("Intel 486 Processor"));  
  304.         }  
  305.         break;  
  306.     case PROCESSOR_INTEL_PENTIUM:  
  307.         {  
  308.             chProcessorType.Format(_T("Intel Pentium Processor"));  
  309.         }  
  310.         break;  
  311.     case PROCESSOR_INTEL_IA64:  
  312.         {  
  313.             chProcessorType.Format(_T("Intel IA64 Processor"));  
  314.         }  
  315.         break;  
  316.     case PROCESSOR_AMD_X8664:  
  317.         {  
  318.             chProcessorType.Format(_T("AMD X8664 Processor"));  
  319.         }  
  320.         break;  
  321.     default:  
  322.         chProcessorType.Format(_T("未知"));  
  323.         break;  
  324.     }  
  325.   
  326.     //GetDisplayName()  
  327. }  
  328.   
  329. void  GetSysInfo::GetMemoryInfo(CString &dwTotalPhys,CString &dwTotalVirtual)   
  330. {   
  331.     //   TODO:     Add   extra   initialization   here   
  332.     MEMORYSTATUS   Mem;   
  333.     //   get   the   memory   status   
  334.     GlobalMemoryStatus(&Mem);   
  335.   
  336.     DWORD dwSize = (DWORD)Mem.dwTotalPhys/(1024*1024);   
  337.     DWORD dwVirtSize = (DWORD)Mem.dwTotalVirtual/(1024*1024);  
  338.   
  339.     dwTotalPhys.Format(_T("物理内存:%ld MB"),dwSize);   
  340.     dwTotalVirtual.Format(_T("虚拟内存:%ld MB"),dwVirtSize);  
  341. }  
  342.   
  343. int GetSysInfo::GetInterFaceCount()  
  344. {  
  345.     /*CGetNetData pNet; 
  346.     DWORD pCount = pNet.GetNetworkInterfacesCount(); 
  347.     return pCount;*/  
  348.   
  349.   
  350.     try  
  351.     {  
  352. #define DEFAULT_BUFFER_SIZE 40960L  
  353.   
  354.         unsigned char *data = (unsigned char*)malloc(DEFAULT_BUFFER_SIZE);  
  355.         DWORD type;  
  356.         DWORD size = DEFAULT_BUFFER_SIZE;  
  357.         DWORD ret;  
  358.   
  359.         char s_key[4096];  
  360.         sprintf_s(s_key , 4096 , "510");  
  361.         //RegQueryValueEx的固定调用格式          
  362.         CString str(s_key);  
  363.   
  364.         //若是RegQueryValueEx函数执行失败则进入循环  
  365.         while((ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, str, 0, &type, data, &size)) != ERROR_SUCCESS)  
  366.         {  
  367.             Sleep(10);  
  368.             //若是RegQueryValueEx的返回值为ERROR_MORE_DATA(申请的内存区data过小,不能容纳RegQueryValueEx返回的数据)  
  369.             if(ret == ERROR_MORE_DATA)   
  370.             {  
  371.                 Sleep(10);  
  372.                 size += DEFAULT_BUFFER_SIZE;  
  373.                 data = (unsigned char*) realloc(data, size);//从新分配足够大的内存  
  374.   
  375.                 ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, str, 0, &type, data, &size);//从新执行RegQueryValueEx函数  
  376.             }   
  377.             //若是RegQueryValueEx返回值仍旧未成功则函数返回.....(注意内存泄露“free函数”~~~)。  
  378.             //这个if保证了这个while只能进入一次~~~避免死循环  
  379.             if(ret != ERROR_SUCCESS)  
  380.             {  
  381.                 if (NULL != data)  
  382.                 {  
  383.                     free(data);  
  384.                     data = NULL;  
  385.                 }  
  386.                 return 0;//0个接口  
  387.             }  
  388.         }  
  389.   
  390.         //函数执行成功以后就是对返回的data内存中数据的解析了,这个建议去查看MSDN有关RegQueryValueEx函数参数数据结构的说明  
  391.         //获得数据块       
  392.         PERF_DATA_BLOCK  *dataBlockPtr = (PERF_DATA_BLOCK *)data;  
  393.         //获得第一个对象  
  394.         PERF_OBJECT_TYPE *objectPtr = (PERF_OBJECT_TYPE *) ((BYTE *)dataBlockPtr + dataBlockPtr->HeaderLength);  
  395.   
  396.         for(int a=0 ; a<(int)dataBlockPtr->NumObjectTypes ; a++)   
  397.         {  
  398.             char nameBuffer[255] = {0};  
  399.             if(objectPtr->ObjectNameTitleIndex == 510)   
  400.             {  
  401.                 DWORD processIdOffset = ULONG_MAX;  
  402.                 PERF_COUNTER_DEFINITION *counterPtr =(PERF_COUNTER_DEFINITION *) ((BYTE *)objectPtr + objectPtr->HeaderLength);  
  403.   
  404.                 for(int b=0 ; b<(int)objectPtr->NumCounters ; b++)   
  405.                 {  
  406.                     if(counterPtr->CounterNameTitleIndex == 520)  
  407.                         processIdOffset = counterPtr->CounterOffset;  
  408.   
  409.                     counterPtr =(PERF_COUNTER_DEFINITION *) ((BYTE *) counterPtr + counterPtr->ByteLength);  
  410.                 }  
  411.   
  412.                 if(processIdOffset == ULONG_MAX) {  
  413.                     if(data != NULL)  
  414.                     {  
  415.                         free(data);  
  416.                         data = NULL;  
  417.                     }  
  418.                     return 0;  
  419.                 }  
  420.   
  421.                 PERF_INSTANCE_DEFINITION *instancePtr =(PERF_INSTANCE_DEFINITION *)  ((BYTE *) objectPtr + objectPtr->DefinitionLength);  
  422.   
  423.                 for(int b=0 ; b<objectPtr->NumInstances ; b++)   
  424.                 {  
  425.                     wchar_t *namePtr = (wchar_t *) ((BYTE *)instancePtr + instancePtr->NameOffset);  
  426.                     PERF_COUNTER_BLOCK *counterBlockPtr = (PERF_COUNTER_BLOCK *) ((BYTE *)instancePtr + instancePtr->ByteLength);  
  427.           
  428.                     char pName[256] = {0};  
  429.                     WideCharToMultiByte(CP_ACP, 0, namePtr, -1, pName, sizeof(nameBuffer), 0, 0);  
  430.   
  431.                     DWORD bandwith = *((DWORD *) ((BYTE *)counterBlockPtr + processIdOffset));                
  432.                     DWORD tottraff = 0;  
  433.   
  434.                     Interfaces.AddTail(CString(pName)); //各网卡的名称  
  435.                     Bandwidths.AddTail(bandwith);       //带宽  
  436.                     TotalTraffics.AddTail(tottraff);    // 流量初始化为0  
  437.   
  438.                     PERF_COUNTER_BLOCK  *pCtrBlk = (PERF_COUNTER_BLOCK *) ((BYTE *)instancePtr + instancePtr->ByteLength);  
  439.   
  440.                       
  441.                     instancePtr = (PERF_INSTANCE_DEFINITION *) ((BYTE *)instancePtr + instancePtr->ByteLength + pCtrBlk->ByteLength);  
  442.                 }  
  443.             }  
  444.             objectPtr = (PERF_OBJECT_TYPE *) ((BYTE *)objectPtr + objectPtr->TotalByteLength);  
  445.         }  
  446.         if(data != NULL)  
  447.         {  
  448.             free(data);  
  449.             data = NULL;  
  450.         }  
  451.     }  
  452.     catch(...)  
  453.     {  
  454.         return 0;  
  455.     }  
  456.     return Interfaces.GetCount();  
  457. }  
  458.   
  459. void GetSysInfo::GetInterFaceName(CString &InterfaceName,int pNum)  
  460. {  
  461.     /*CGetNetData pNet; 
  462.     pNet.GetNetworkInterfaceName(&InterfaceName,pNum);*/  
  463.   
  464.     POSITION pos = Interfaces.FindIndex(pNum);  
  465.     if(pos==NULL)  
  466.         return ;  
  467.   
  468.     InterfaceName = Interfaces.GetAt(pos);  
  469.     pos = Bandwidths.FindIndex(pNum);  
  470.     if (pos == NULL)  
  471.         return;  
  472.     DWORD dwBandwidth = Bandwidths.GetAt(pos);  
  473.   
  474.     CString str;  
  475.     str.Format(_T("%d"),dwBandwidth);  
  476.   
  477.     InterfaceName = InterfaceName + str;  
  478. }  
  479.   
  480. void GetSysInfo::GetDiskInfo(DWORD &dwNum,CString chDriveInfo[])  
  481. {  
  482.     DWORD DiskCount = 0;  
  483.   
  484.     //利用GetLogicalDrives()函数能够获取系统中逻辑驱动器的数量,函数返回的是一个32位无符号整型数据。  
  485.     DWORD DiskInfo = GetLogicalDrives();  
  486.   
  487.     //经过循环操做查看每一位数据是否为1,若是为1则磁盘为真,若是为0则磁盘不存在。  
  488.     while(DiskInfo)  
  489.     {  
  490.         //经过位运算的逻辑与操做,判断是否为1  
  491.         Sleep(10);  
  492.         if(DiskInfo&1)  
  493.         {  
  494.             DiskCount++;  
  495.         }  
  496.         DiskInfo = DiskInfo >> 1;//经过位运算的右移操做保证每循环一次所检查的位置向右移动一位。*/  
  497.     }  
  498.   
  499.     if (dwNum < DiskCount)  
  500.     {  
  501.         return;//实际的磁盘数目大于dwNum  
  502.     }  
  503.     dwNum = DiskCount;//将磁盘分区数量保存  
  504.   
  505.   
  506.     //-------------------------------------------------------------------//  
  507.     //经过GetLogicalDriveStrings()函数获取全部驱动器字符串信息长度  
  508.     int DSLength = GetLogicalDriveStrings(0,NULL);  
  509.   
  510.       WCHAR* DStr = new WCHAR[DSLength];  
  511.       memset(DStr,0,DSLength);  
  512.   
  513.       //经过GetLogicalDriveStrings将字符串信息复制到堆区数组中,其中保存了全部驱动器的信息。  
  514.       GetLogicalDriveStrings(DSLength,DStr);  
  515.   
  516.       int DType;  
  517.       int si=0;  
  518.       BOOL fResult;  
  519.       unsigned _int64 i64FreeBytesToCaller;  
  520.       unsigned _int64 i64TotalBytes;  
  521.       unsigned _int64 i64FreeBytes;  
  522.   
  523.       //读取各驱动器信息,因为DStr内部数据格式是A:\NULLB:\NULLC:\NULL,因此DSLength/4能够得到具体大循环范围  
  524.       for(int i=0;i<DSLength/4;++i)  
  525.       {  
  526.           Sleep(10);  
  527.           CString strdriver = DStr+i*4;  
  528.           CString strTmp,strTotalBytes,strFreeBytes;  
  529.           DType = GetDriveType(strdriver);//GetDriveType函数,能够获取驱动器类型,参数为驱动器的根目录  
  530.           switch (DType)  
  531.           {  
  532.           case DRIVE_FIXED:  
  533.               {  
  534.                   strTmp.Format(_T("本地磁盘"));  
  535.               }  
  536.             break;  
  537.           case DRIVE_CDROM:  
  538.               {  
  539.                   strTmp.Format(_T("DVD驱动器"));  
  540.               }  
  541.               break;  
  542.           case DRIVE_REMOVABLE:  
  543.               {  
  544.                   strTmp.Format(_T("可移动磁盘"));  
  545.               }  
  546.               break;  
  547.           case DRIVE_REMOTE:  
  548.               {  
  549.                   strTmp.Format(_T("网络磁盘"));  
  550.               }  
  551.               break;  
  552.           case DRIVE_RAMDISK:  
  553.               {  
  554.                   strTmp.Format(_T("虚拟RAM磁盘"));  
  555.               }  
  556.               break;  
  557.           case DRIVE_UNKNOWN:  
  558.               {  
  559.                   strTmp.Format(_T("虚拟RAM未知设备"));  
  560.               }  
  561.               break;  
  562.           default:  
  563.               strTmp.Format(_T("未知设备"));  
  564.               break;  
  565.           }  
  566.   
  567.           //GetDiskFreeSpaceEx函数,能够获取驱动器磁盘的空间状态,函数返回的是个BOOL类型数据  
  568.           fResult = GetDiskFreeSpaceEx (strdriver,  
  569.               (PULARGE_INTEGER)&i64FreeBytesToCaller,  
  570.               (PULARGE_INTEGER)&i64TotalBytes,  
  571.               (PULARGE_INTEGER)&i64FreeBytes);  
  572.                 
  573.           if(fResult)  
  574.           {  
  575.               strTotalBytes.Format(_T("磁盘总容量%fMB"),(float)i64TotalBytes/1024/1024);  
  576.               strFreeBytes.Format(_T("磁盘剩余空间%fMB"),(float)i64FreeBytesToCaller/1024/1024);  
  577.           }  
  578.           else  
  579.           {  
  580.               strTotalBytes.Format(_T(""));  
  581.               strFreeBytes.Format(_T(""));  
  582.           }  
  583.           chDriveInfo[i] = strTmp + _T("(") + strdriver + _T("):") + strTotalBytes + strFreeBytes;  
  584.           si+=4;  
  585.       }  
  586. }  
  587.   
  588. void GetSysInfo::GetDisplayCardInfo(DWORD &dwNum,CString chCardName[])  
  589. {  
  590.     HKEY keyServ;  
  591.     HKEY keyEnum;  
  592.     HKEY key;  
  593.     HKEY key2;  
  594.     LONG lResult;//LONG型变量-保存函数返回值  
  595.   
  596.     //查询"SYSTEM\\CurrentControlSet\\Services"下的全部子键保存到keyServ  
  597.     lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Services"),0,KEY_READ,&keyServ);  
  598.     if (ERROR_SUCCESS != lResult)  
  599.         return;  
  600.   
  601.   
  602.     //查询"SYSTEM\\CurrentControlSet\\Enum"下的全部子键保存到keyEnum  
  603.     lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Enum"),0,KEY_READ,&keyEnum);  
  604.     if (ERROR_SUCCESS != lResult)  
  605.         return;  
  606.   
  607.     int i = 0,count = 0;  
  608.     DWORD size = 0,type = 0;  
  609.     for (;;++i)  
  610.     {  
  611.         Sleep(5);  
  612.         size = 512;  
  613.         TCHAR name[512] = {0};//保存keyServ下各子项的字段名称  
  614.   
  615.         //逐个枚举keyServ下的各子项字段保存到name中  
  616.         lResult = RegEnumKeyEx(keyServ,i,name,&size,NULL,NULL,NULL,NULL);  
  617.   
  618.         //要读取的子项不存在,即keyServ的子项所有遍历完时跳出循环  
  619.         if(lResult == ERROR_NO_MORE_ITEMS)  
  620.             break;  
  621.   
  622.         //打开keyServ的子项字段为name所标识的字段的值保存到key  
  623.         lResult = RegOpenKeyEx(keyServ,name,0,KEY_READ,&key);  
  624.         if (lResult != ERROR_SUCCESS)  
  625.         {  
  626.             RegCloseKey(keyServ);  
  627.             return;  
  628.         }  
  629.           
  630.   
  631.         size = 512;  
  632.         //查询key下的字段为Group的子键字段名保存到name  
  633.         lResult = RegQueryValueEx(key,TEXT("Group"),0,&type,(LPBYTE)name,&size);  
  634.         if(lResult == ERROR_FILE_NOT_FOUND)  
  635.         {  
  636.             //?键不存在  
  637.             RegCloseKey(key);  
  638.             continue;  
  639.         };  
  640.   
  641.   
  642.   
  643.         //若是查询到的name不是Video则说明该键不是显卡驱动项  
  644.         if(_tcscmp(TEXT("Video"),name)!=0)  
  645.         {  
  646.             RegCloseKey(key);  
  647.             continue;     //返回for循环  
  648.         };  
  649.           
  650.         //若是程序继续往下执行的话说明已经查到了有关显卡的信息,因此在下面的代码执行完以后要break第一个for循环,函数返回