获取系统硬件信息
2016-08-01 17:51
197 查看
由于项目需要,要求做一个服务器的实时性能监控(CPU、内存、网络利用率等)和读取服务器的硬件配置参数的接口供项目组使用,就是一个类似于鲁大师之类的东东吧...
还有一种方案就是--->“强大”的WMI,.net平台的程序员可能对这个比较熟悉,WMI即windows管理规范。通过它可以访问、配置、管理和监视几乎所有的Windows资源。当然对于程序员而言在WMI体系结构中我们最需要关心的就是WMI提供的程序和接口。
WMI提供程序在WMI和托管资源之间扮演着中间方的角色。提供程序代表使用者应用程序和脚本从WMI托管资源请求信息,并发送指令到WMI托管资源。
下面是我们利用WMI编程经常要用到的WMI内置提供程序清单,以供编程参考。
1.Active Directory提供程序
链接库文件:dsprov.dll
命名空间:rootdirectoryldap
作用:将Active Directory 对象映射到 WMI。
2.事件日志提供程序
链接库文件:ntevt.dll
命名空间:rootcimv2
作用:管理 Windows 事件日志,例如,读取、备份、清除、复制、删除、监视、重命名、压缩、解压缩和更改事件日志设置。
3.注册表提供程序
链接库文件:stdprov.dll
命名空间:rootdefault
作用:读取、写入、枚举、监视、创建、删除注册表项和值。
4.Win32 提供程序
链接库文件:cimwin32.dll
命名空间:rootcimv2
作用:提供关于计算机、磁盘、外围设备、文件、文件夹、文件系统、网络组件、操作系统、打印机、进程、安全性、服务、共享、SAM 用户及组,以及更多资源的信息。
5.Windows 安装程序提供程序
链接库文件:msiprov.dll
命名空间:rootcimv2
作用:提供对已安装软件信息的访问。
以上可以看出WMI中的类被分组到不同的命名空间中,所以我们在调用相应的程序库时要注意引入对应的命名空间~~~我们今天用到的库就是cimwin32.dll库(第4个)。
好,废话到此为止,还有不懂的自己下去慢慢研究:现在看代码...
一、基于API方式的实现代码,简单的对部分API函数的封装:
1、GetSysInfo.h文件
2.GetSysInfo.cpp文件
以上就是对系统API的简单封装,可以看出用的最多的就是RegOpenKeyEx、RegQueryValueEx之类的查询注册表的函数,基本上所有系统信息都可以通过注册表查到,所以...感兴趣的童鞋有空可以去研究研究注册表~~~~~~这里只是提供一个思路也许有更好的方法来实现~~~求交流~~
二、通过WMI(windows管理规范)接口编程来实现系统硬件信息的获取~~这个相较于上面API方式就方便多了~~~使用起来是相当的方面~~~但是....但是.....这个他妈的实在是太慢了~~~~~比上面的API方式要慢很多倍~~~我没有试过WMI在.net平台下的效果,但至少在MFC工程里面是相当的慢,看代码~~
1、WMIInfo.h文件
上面就是一个WMI的封装,返回参数均以CString类型返回调用顺序:
1.实例化一个CWmiInfo类对象
2.调用InitWmi()函数初始化COM组件等。。。函数中有说明必须调用InitWmi初始化WMI组件,否则所有调用都无意义。
3.调用GetXXX方法获取你要获取的字段值。
4.最后使用完CWmiInfo类对象之后一定要记得调用ReleaseWmi()函数来释放资源
调用说明:
WMI的字段类名好像都是以Win32_开头。。。。如:Win32_Processor,Win32_PhysicalMemory等等。。。所以,你只要在MSDN输入Win32_就会看到很多以WMI结尾的类了。。。剩下的就是你的English水平问题了,这里google也可以帮你,如果你需要的话。
下面给大家列出一些常用的类名:
view plain
// 硬件信息类名
Win32_Processor, // CPU 处理器
Win32_PhysicalMemory, // 物理内存条
Win32_Keyboard, // 键盘
Win32_PointingDevice, // 点输入设备,包括鼠标。
Win32_FloppyDrive, // 软盘驱动器
Win32_DiskDrive, // 硬盘驱动器
Win32_CDROMDrive, // 光盘驱动器
Win32_BaseBoard, // 主板
Win32_BIOS, // BIOS 芯片
Win32_ParallelPort, // 并口
Win32_SerialPort, // 串口
Win32_SerialPortConfiguration, // 串口配置
Win32_SoundDevice, // 多媒体设置,一般指声卡。
Win32_SystemSlot, // 主板插槽 (ISA & PCI & AGP)
Win32_USBController, // USB 控制器
Win32_NetworkAdapter, // 网络适配器
Win32_NetworkAdapterConfiguration, // 网络适配器设置
Win32_Printer, // 打印机
Win32_PrinterConfiguration, // 打印机设置
Win32_PrintJob, // 打印机任务
Win32_TCPIPPrinterPort, // 打印机端口
Win32_POTSModem, // MODEM
Win32_POTSModemToSerialPort, // MODEM 端口
Win32_DesktopMonitor, // 显示器
Win32_DisplayConfiguration, // 显卡
Win32_DisplayControllerConfiguration, // 显卡设置
Win32_VideoController, // 显卡细节。
Win32_VideoSettings, // 显卡支持的显示模式。
// 操作系统
Win32_TimeZone, // 时区
Win32_SystemDriver, // 驱动程序
Win32_DiskPartition, // 磁盘分区
Win32_LogicalDisk, // 逻辑磁盘
Win32_LogicalDiskToPartition, // 逻辑磁盘所在分区及始末位置。
Win32_LogicalMemoryConfiguration, // 逻辑内存配置
Win32_PageFile, // 系统页文件信息
Win32_PageFileSetting, // 页文件设置
Win32_BootConfiguration, // 系统启动配置
Win32_ComputerSystem, // 计算机信息简要
Win32_OperatingSystem, // 操作系统信息
Win32_StartupCommand, // 系统自动启动程序
Win32_Service, // 系统安装的服务
Win32_Group, // 系统管理组
Win32_GroupUser, // 系统组帐号
Win32_UserAccount, // 用户帐号
Win32_Process, // 系统进程
Win32_Thread, // 系统线程
Win32_Share, // 共享
Win32_NetworkClient, // 已安装的网络客户端
Win32_NetworkProtocol, // 已安装的网络协议
在、msdn中输入相应的类名即可查看个类中包括的类成员及其含义~~
以上代码均已在vs2008中编译通过~~~~可以直接使用~~~~~~有不当的地方请指教!!
还有一种方案就是--->“强大”的WMI,.net平台的程序员可能对这个比较熟悉,WMI即windows管理规范。通过它可以访问、配置、管理和监视几乎所有的Windows资源。当然对于程序员而言在WMI体系结构中我们最需要关心的就是WMI提供的程序和接口。
WMI提供程序在WMI和托管资源之间扮演着中间方的角色。提供程序代表使用者应用程序和脚本从WMI托管资源请求信息,并发送指令到WMI托管资源。
下面是我们利用WMI编程经常要用到的WMI内置提供程序清单,以供编程参考。
1.Active Directory提供程序
链接库文件:dsprov.dll
命名空间:rootdirectoryldap
作用:将Active Directory 对象映射到 WMI。
2.事件日志提供程序
链接库文件:ntevt.dll
命名空间:rootcimv2
作用:管理 Windows 事件日志,例如,读取、备份、清除、复制、删除、监视、重命名、压缩、解压缩和更改事件日志设置。
3.注册表提供程序
链接库文件:stdprov.dll
命名空间:rootdefault
作用:读取、写入、枚举、监视、创建、删除注册表项和值。
4.Win32 提供程序
链接库文件:cimwin32.dll
命名空间:rootcimv2
作用:提供关于计算机、磁盘、外围设备、文件、文件夹、文件系统、网络组件、操作系统、打印机、进程、安全性、服务、共享、SAM 用户及组,以及更多资源的信息。
5.Windows 安装程序提供程序
链接库文件:msiprov.dll
命名空间:rootcimv2
作用:提供对已安装软件信息的访问。
以上可以看出WMI中的类被分组到不同的命名空间中,所以我们在调用相应的程序库时要注意引入对应的命名空间~~~我们今天用到的库就是cimwin32.dll库(第4个)。
好,废话到此为止,还有不懂的自己下去慢慢研究:现在看代码...
一、基于API方式的实现代码,简单的对部分API函数的封装:
1、GetSysInfo.h文件
pragma once #include <afxtempl.h> class GetSysInfo { public: GetSysInfo(void); ~GetSysInfo(void); public: void GetOSVersion(CString &strOSVersion,CString &strServiceVersion); BOOL IsWow64();//判断是否为64位操作系统 int GetInterFaceCount(); void GetInterFaceName(CString &InterfaceName,int pNum); void GetMemoryInfo(CString &dwTotalPhys,CString &dwTotalVirtual); 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; //各网卡的总流量 };
2.GetSysInfo.cpp文件
#include "StdAfx.h" #include "GetSysInfo.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 Editionn")); } break; case VER_PLATFORM_WIN32s: str.Format(_T("Microsoft Win32sn")); 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() { 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) { 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; } }
以上就是对系统API的简单封装,可以看出用的最多的就是RegOpenKeyEx、RegQueryValueEx之类的查询注册表的函数,基本上所有系统信息都可以通过注册表查到,所以...感兴趣的童鞋有空可以去研究研究注册表~~~~~~这里只是提供一个思路也许有更好的方法来实现~~~求交流~~
二、通过WMI(windows管理规范)接口编程来实现系统硬件信息的获取~~这个相较于上面API方式就方便多了~~~使用起来是相当的方面~~~但是....但是.....这个他妈的实在是太慢了~~~~~比上面的API方式要慢很多倍~~~我没有试过WMI在.net平台下的效果,但至少在MFC工程里面是相当的慢,看代码~~
1、WMIInfo.h文件
<span style="background-color: rgb(255, 255, 255);">#pragma once #include <atlbase.h> #include <afxpriv.h> #include <WbemIdl.h> #pragma comment(lib,"WbemUuid.lib") class CWmiInfo { public: CWmiInfo(void); ~CWmiInfo(void); public: HRESULT InitWmi(); //初始化WMI HRESULT ReleaseWmi(); //释放 BOOL GetSingleItemInfo(CString,CString,CString&);<pre class="cpp" name="code" style="margin-top: 4px; margin-right: 0px; margin-bottom: 4px; margin-left: 0px; background-color: rgb(240, 240, 240); "> BOOL GetGroupItemInfo(CString,CString[],int,CString&); private: void VariantToString(const LPVARIANT,CString &) const;//将Variant类型的变量转换为CString private: IEnumWbemClassObject* m_pEnumClsObj; IWbemClassObject* m_pWbemClsObj; IWbemServices* m_pWbemSvc; IWbemLocator* m_pWbemLoc; }; 2.WMIInfo.CPP文件 view plain #include "StdAfx.h" #include "WmiInfo.h" CWmiInfo::CWmiInfo(void) { m_pWbemSvc=NULL; m_pWbemLoc=NULL; m_pEnumClsObj = NULL; } CWmiInfo::~CWmiInfo(void) { m_pWbemSvc=NULL; m_pWbemLoc=NULL; m_pEnumClsObj = NULL; } HRESULT CWmiInfo::InitWmi() { HRESULT hr; //一、初始化COM组件 //初始化COM hr=::CoInitializeEx(0,COINIT_MULTITHREADED); if (SUCCEEDED(hr) || RPC_E_CHANGED_MODE == hr) { //设置进程的安全级别,(调用COM组件时在初始化COM之后要调用CoInitializeSecurity设置进程安全级别,否则会被系统识别为病毒) hr=CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); //VERIFY(SUCCEEDED(hr)); //二、创建一个WMI命名空间连接 //创建一个CLSID_WbemLocator对象 hr=CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&m_pWbemLoc); VERIFY(SUCCEEDED(hr)); //使用m_pWbemLoc连接到"rootcimv2"并设置m_pWbemSvc的指针 hr=m_pWbemLoc->ConnectServer(CComBSTR(L"ROOT\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &m_pWbemSvc); VERIFY(SUCCEEDED(hr)); //三、设置WMI连接的安全性 hr=CoSetProxyBlanket(m_pWbemSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); VERIFY(SUCCEEDED(hr)); } return(hr); } HRESULT CWmiInfo::ReleaseWmi() { HRESULT hr; if (NULL != m_pWbemSvc) { hr=m_pWbemSvc->Release(); } if (NULL != m_pWbemLoc) { hr=m_pWbemLoc->Release(); } if (NULL != m_pEnumClsObj) { hr=m_pEnumClsObj->Release(); } ::CoUninitialize(); return(hr); } BOOL CWmiInfo::GetSingleItemInfo(CString ClassName,CString ClassMember,CString &chRetValue) { USES_CONVERSION; CComBSTR query("SELECT * FROM "); VARIANT vtProp; ULONG uReturn; HRESULT hr; BOOL bRet = FALSE; if (NULL != m_pWbemSvc) { //查询类ClassName中的所有字段,保存到m_pEnumClsObj中 query+=CComBSTR(ClassName); hr=m_pWbemSvc->ExecQuery(CComBSTR("WQL"),query,WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY, 0,&m_pEnumClsObj); if (SUCCEEDED(hr)) { //初始化vtProp值 VariantInit(&vtProp); uReturn=0; //返回从当前位置起的第一个对象到m_pWbemClsObj中 hr=m_pEnumClsObj->Next(WBEM_INFINITE,1,&m_pWbemClsObj,&uReturn); if(SUCCEEDED(hr)&&uReturn>0) { //从m_pWbemClsObj中找出ClassMember标识的成员属性值,并保存到vtProp变量中 hr=m_pWbemClsObj->Get(CComBSTR(ClassMember),0,&vtProp,0,0); if (SUCCEEDED(hr)) { VariantToString(&vtProp,chRetValue); VariantClear(&vtProp);//清空vtProp bRet = TRUE; } } } } if(NULL != m_pEnumClsObj) { hr=m_pEnumClsObj->Release(); m_pEnumClsObj = NULL; } if(NULL != m_pWbemClsObj) { hr=m_pWbemClsObj->Release(); m_pWbemClsObj = NULL; } return bRet; } BOOL CWmiInfo::GetGroupItemInfo(CString ClassName,CString ClassMember[],int n,CString &chRetValue) { USES_CONVERSION; CComBSTR query("SELECT * FROM "); CString result,info; VARIANT vtProp; ULONG uReturn; HRESULT hr; int i; BOOL bRet = FALSE; if (NULL != m_pWbemSvc) { query+=CComBSTR(ClassName); hr=m_pWbemSvc->ExecQuery(CComBSTR("WQL"),query,WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY,0,&m_pEnumClsObj); if (SUCCEEDED(hr)) { VariantInit(&vtProp); //初始化vtProp变量 if(m_pEnumClsObj) { Sleep(10); uReturn=0; hr=m_pEnumClsObj->Next(WBEM_INFINITE,1,&m_pWbemClsObj,&uReturn); if (SUCCEEDED(hr) &&uReturn>0) { for(i=0;i<n;++i) { hr=m_pWbemClsObj->Get(CComBSTR(ClassMember[i]),0,&vtProp,0,0); if (SUCCEEDED(hr)) { VariantToString(&vtProp,info); chRetValue+=info+_T("t"); VariantClear(&vtProp); bRet = TRUE; } } chRetValue+=_T("rn"); } } } } if(NULL != m_pEnumClsObj) { hr=m_pEnumClsObj->Release(); m_pEnumClsObj=NULL; } if(NULL != m_pWbemClsObj) { hr=m_pWbemClsObj->Release(); m_pWbemClsObj=NULL; } return bRet; } void CWmiInfo::VariantToString(const LPVARIANT pVar,CString &chRetValue) const { USES_CONVERSION; CComBSTR HUGEP* pBstr; BYTE HUGEP* pBuf; LONG low,high,i; HRESULT hr; switch(pVar->vt) { case VT_BSTR: { chRetValue=W2T(pVar->bstrVal); } break; case VT_BOOL: { if(VARIANT_TRUE==pVar->boolVal) chRetValue="是"; else chRetValue="否"; } break; case VT_I4: { chRetValue.Format(_T("%d"),pVar->lVal); } break; case VT_UI1: { chRetValue.Format(_T("%d"),pVar->bVal); } break; case VT_UI4: { chRetValue.Format(_T("%d"),pVar->ulVal); } break; case VT_BSTR|VT_ARRAY: { hr=SafeArrayAccessData(pVar->parray,(void HUGEP**)&pBstr); hr=SafeArrayUnaccessData(pVar->parray); chRetValue=W2T(pBstr->m_str); } break; case VT_I4|VT_ARRAY: { SafeArrayGetLBound(pVar->parray,1,&low); SafeArrayGetUBound(pVar->parray,1,&high); hr=SafeArrayAccessData(pVar->parray,(void HUGEP**)&pBuf); hr=SafeArrayUnaccessData(pVar->parray); CString strTmp; high=min(high,MAX_PATH*2-1); for(i=low;i<=high;++i) { strTmp.Format(_T("X"),pBuf[i]); chRetValue+=strTmp; } } break; default: break; } } </span>
上面就是一个WMI的封装,返回参数均以CString类型返回调用顺序:
1.实例化一个CWmiInfo类对象
2.调用InitWmi()函数初始化COM组件等。。。函数中有说明必须调用InitWmi初始化WMI组件,否则所有调用都无意义。
3.调用GetXXX方法获取你要获取的字段值。
4.最后使用完CWmiInfo类对象之后一定要记得调用ReleaseWmi()函数来释放资源
调用说明:
WMI的字段类名好像都是以Win32_开头。。。。如:Win32_Processor,Win32_PhysicalMemory等等。。。所以,你只要在MSDN输入Win32_就会看到很多以WMI结尾的类了。。。剩下的就是你的English水平问题了,这里google也可以帮你,如果你需要的话。
下面给大家列出一些常用的类名:
view plain
// 硬件信息类名
Win32_Processor, // CPU 处理器
Win32_PhysicalMemory, // 物理内存条
Win32_Keyboard, // 键盘
Win32_PointingDevice, // 点输入设备,包括鼠标。
Win32_FloppyDrive, // 软盘驱动器
Win32_DiskDrive, // 硬盘驱动器
Win32_CDROMDrive, // 光盘驱动器
Win32_BaseBoard, // 主板
Win32_BIOS, // BIOS 芯片
Win32_ParallelPort, // 并口
Win32_SerialPort, // 串口
Win32_SerialPortConfiguration, // 串口配置
Win32_SoundDevice, // 多媒体设置,一般指声卡。
Win32_SystemSlot, // 主板插槽 (ISA & PCI & AGP)
Win32_USBController, // USB 控制器
Win32_NetworkAdapter, // 网络适配器
Win32_NetworkAdapterConfiguration, // 网络适配器设置
Win32_Printer, // 打印机
Win32_PrinterConfiguration, // 打印机设置
Win32_PrintJob, // 打印机任务
Win32_TCPIPPrinterPort, // 打印机端口
Win32_POTSModem, // MODEM
Win32_POTSModemToSerialPort, // MODEM 端口
Win32_DesktopMonitor, // 显示器
Win32_DisplayConfiguration, // 显卡
Win32_DisplayControllerConfiguration, // 显卡设置
Win32_VideoController, // 显卡细节。
Win32_VideoSettings, // 显卡支持的显示模式。
// 操作系统
Win32_TimeZone, // 时区
Win32_SystemDriver, // 驱动程序
Win32_DiskPartition, // 磁盘分区
Win32_LogicalDisk, // 逻辑磁盘
Win32_LogicalDiskToPartition, // 逻辑磁盘所在分区及始末位置。
Win32_LogicalMemoryConfiguration, // 逻辑内存配置
Win32_PageFile, // 系统页文件信息
Win32_PageFileSetting, // 页文件设置
Win32_BootConfiguration, // 系统启动配置
Win32_ComputerSystem, // 计算机信息简要
Win32_OperatingSystem, // 操作系统信息
Win32_StartupCommand, // 系统自动启动程序
Win32_Service, // 系统安装的服务
Win32_Group, // 系统管理组
Win32_GroupUser, // 系统组帐号
Win32_UserAccount, // 用户帐号
Win32_Process, // 系统进程
Win32_Thread, // 系统线程
Win32_Share, // 共享
Win32_NetworkClient, // 已安装的网络客户端
Win32_NetworkProtocol, // 已安装的网络协议
在、msdn中输入相应的类名即可查看个类中包括的类成员及其含义~~
以上代码均已在vs2008中编译通过~~~~可以直接使用~~~~~~有不当的地方请指教!!
相关文章推荐
- poj 1611 The Suspects(简单并查集)
- android 反编译 smali 调试
- 查看文件夹大小及所属用户组
- 企业SaaS平台AppDirect收购云搜索Xendo,将支持同时检索多个应用
- Java Spring 中你不知道的注入方式
- ffmpeg 初学之视频切片
- 分享:DevC++出现[Error] ld returned 1 exit status,如何解决才好呢?
- 笔记③:POJ Roadblocks 次短路问题代码解析(优先队列逆序排列两种方法)
- Python基础知识(2)——函数
- Android弹出对话框--Alertdialog(系统自带的)
- codevs 1124线段覆盖(贪心)
- 设计模式之命令者
- AngularJS基础 ng-include 指令示例讲解
- Android 开发之百度地图——百度推送
- HDU 2795 Billboard
- poj 1472 Instant Complexity
- js实现网页和控件的简单交互
- 文件压缩
- iOS依赖库管理工具之Carthage
- CSS3 flex的使用方法