获取系统硬件信息
来源:互联网 发布:南方数据粘贴 编辑:程序博客网 时间:2024/05/16 15:08
由于项目需要,要求做一个服务器的实时性能监控(CPU、内存、网络利用率等)和读取服务器的硬件配置参数的接口供项目组使用,就是一个类似于鲁大师之类的东东吧...
下面是我们利用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
作用:提供对已安装软件信息的访问。
好,废话到此为止,还有不懂的自己下去慢慢研究:现在看代码...
一、基于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;
- }
- }
二、通过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也可以帮你,如果你需要的话。
下面给大家列出一些常用的类名:
-
// 硬件信息类名 - 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_NetworkAdapterConfigurat
ion, // 网络适配器设置 - Win32_Printer,
// 打印机 - Win32_PrinterConfiguration,
// 打印机设置 - Win32_PrintJob,
// 打印机任务 - Win32_TCPIPPrinterPort,
// 打印机端口 - Win32_POTSModem,
// MODEM - Win32_POTSModemToSerialPort,
// MODEM 端口 - Win32_DesktopMonitor,
// 显示器 - Win32_DisplayConfiguration,
// 显卡 - Win32_DisplayControllerConfigu
ration, // 显卡设置 - Win32_VideoController,
// 显卡细节。 - Win32_VideoSettings,
// 显卡支持的显示模式。 -
- //
操作系统 - Win32_TimeZone,
// 时区 - Win32_SystemDriver,
// 驱动程序 - Win32_DiskPartition,
// 磁盘分区 - Win32_LogicalDisk,
// 逻辑磁盘 - Win32_LogicalDiskToPartition,
// 逻辑磁盘所在分区及始末位置。 - Win32_LogicalMemoryConfigurati
on, // 逻辑内存配置 - 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,
// 已安装的网络协议
- 获取系统硬件信息
- 获取系统硬件信息
- 获取系统硬件信息
- 获取系统硬件信息
- 获取系统硬件信息
- javascript 获取系统硬件信息
- 获取ios 系统 硬件信息
- C# 获取系统硬件信息
- unity3d 获取系统硬件信息
- python获取系统硬件信息
- unity3d 获取系统硬件信息
- .NET中获取系统硬件信息
- WMI获取系统硬件软件信息
- js 获取客户端 浏览器 系统 硬件信息
- Dart获取系统和硬件信息
- lscpu 获取系统的硬件信息
- C++获取系统信息(IP地址、硬件信息等)
- 获取 手机基本配置信息 硬件 系统信息 辅助类
- 为RecyclerView添加Header和Footer,支持三种LayoutManager
- 数组单调和
- ASP.NET URL重写(伪静态)
- Ionic 安装部署
- 二维码的使用
- 获取系统硬件信息
- [RK3288][Android6.0] WiFi之Autojoin对无线网络的选择机制
- spark集群环境与任务调参
- 异步加载——MVP
- Wireshark网络抓包(一)——数据包、着色规则和提示
- 日常充电之--PHP表单验证
- 七、C_base——函数
- Dedecms网站服务器如何搬家?
- [Leetcode] 273. Integer to English Words 解题报告