转自:http://blog.csdn.net/ly402609921/article/details/7446943

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

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

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

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个)。
好,废话到此为止,还有不懂的自己下去慢慢研究:现在看代码...

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

1、GetSysInfo.h文件

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

2.GetSysInfo.cpp文件

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

以上就是对系统API的简单封装,可以看出用的最多的就是RegOpenKeyEx、RegQueryValueEx之类的查询注册表的函数,基本上所有系统信息都可以通过注册表查到,所以...感兴趣的童鞋有空可以去研究研究注册表~~~~~~这里只是提供一个思路也许有更好的方法来实现~~~求交流~~

二、通过WMI(windows管理规范)接口编程来实现系统硬件信息的获取~~这个相较于上面API方式就方便多了~~~使用起来是相当的方面~~~但是....但是.....这个他妈的实在是太慢了~~~~~比上面的API方式要慢很多倍~~~我没有试过WMI在.net平台下的效果,但至少在MFC工程里面是相当的慢,看代码~~

1、WMIInfo.h文件

[cpp]  view plain copy
  1. #pragma once
  2. #include <atlbase.h>
  3. #include <afxpriv.h>
  4. #include <WbemIdl.h>
  5. #pragma comment(lib,"WbemUuid.lib")
  6. class CWmiInfo
  7. {
  8. public:
  9. CWmiInfo(void);
  10. ~CWmiInfo(void);
  11. public:
  12. HRESULT InitWmi();    //初始化WMI
  13. HRESULT ReleaseWmi(); //释放
  14. 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&);
  15. private:
  16. void VariantToString(const LPVARIANT,CString &) const;//将Variant类型的变量转换为CString
  17. private:
  18. IEnumWbemClassObject* m_pEnumClsObj;
  19. IWbemClassObject* m_pWbemClsObj;
  20. IWbemServices* m_pWbemSvc;
  21. IWbemLocator* m_pWbemLoc;
  22. };

2.WMIInfo.CPP文件

[cpp]  view plain copy
  1. #include "StdAfx.h"
  2. #include "WmiInfo.h"
  3. CWmiInfo::CWmiInfo(void)
  4. {
  5. m_pWbemSvc=NULL;
  6. m_pWbemLoc=NULL;
  7. m_pEnumClsObj = NULL;
  8. }
  9. CWmiInfo::~CWmiInfo(void)
  10. {
  11. m_pWbemSvc=NULL;
  12. m_pWbemLoc=NULL;
  13. m_pEnumClsObj = NULL;
  14. }
  15. HRESULT CWmiInfo::InitWmi()
  16. {
  17. HRESULT hr;
  18. //一、初始化COM组件
  19. //初始化COM
  20. hr=::CoInitializeEx(0,COINIT_MULTITHREADED);
  21. if (SUCCEEDED(hr) || RPC_E_CHANGED_MODE == hr)
  22. {
  23. //设置进程的安全级别,(调用COM组件时在初始化COM之后要调用CoInitializeSecurity设置进程安全级别,否则会被系统识别为病毒)
  24. hr=CoInitializeSecurity(NULL,
  25. -1,
  26. NULL,
  27. NULL,
  28. RPC_C_AUTHN_LEVEL_PKT,
  29. RPC_C_IMP_LEVEL_IMPERSONATE,
  30. NULL,
  31. EOAC_NONE,
  32. NULL);
  33. //VERIFY(SUCCEEDED(hr));
  34. //二、创建一个WMI命名空间连接
  35. //创建一个CLSID_WbemLocator对象
  36. hr=CoCreateInstance(CLSID_WbemLocator,
  37. 0,
  38. CLSCTX_INPROC_SERVER,
  39. IID_IWbemLocator,
  40. (LPVOID*)&m_pWbemLoc);
  41. VERIFY(SUCCEEDED(hr));
  42. //使用m_pWbemLoc连接到"root\cimv2"并设置m_pWbemSvc的指针
  43. hr=m_pWbemLoc->ConnectServer(CComBSTR(L"ROOT\\CIMV2"),
  44. NULL,
  45. NULL,
  46. 0,
  47. NULL,
  48. 0,
  49. 0,
  50. &m_pWbemSvc);
  51. VERIFY(SUCCEEDED(hr));
  52. //三、设置WMI连接的安全性
  53. hr=CoSetProxyBlanket(m_pWbemSvc,
  54. RPC_C_AUTHN_WINNT,
  55. RPC_C_AUTHZ_NONE,
  56. NULL,
  57. RPC_C_AUTHN_LEVEL_CALL,
  58. RPC_C_IMP_LEVEL_IMPERSONATE,
  59. NULL,
  60. EOAC_NONE);
  61. VERIFY(SUCCEEDED(hr));
  62. }
  63. return(hr);
  64. }
  65. HRESULT CWmiInfo::ReleaseWmi()
  66. {
  67. HRESULT hr;
  68. if (NULL != m_pWbemSvc)
  69. {
  70. hr=m_pWbemSvc->Release();
  71. }
  72. if (NULL != m_pWbemLoc)
  73. {
  74. hr=m_pWbemLoc->Release();
  75. }
  76. if (NULL != m_pEnumClsObj)
  77. {
  78. hr=m_pEnumClsObj->Release();
  79. }
  80. ::CoUninitialize();
  81. return(hr);
  82. }
  83. BOOL CWmiInfo::GetSingleItemInfo(CString ClassName,CString ClassMember,CString &chRetValue)
  84. {
  85. USES_CONVERSION;
  86. CComBSTR query("SELECT * FROM ");
  87. VARIANT vtProp;
  88. ULONG uReturn;
  89. HRESULT hr;
  90. BOOL bRet = FALSE;
  91. if (NULL != m_pWbemSvc)
  92. {
  93. //查询类ClassName中的所有字段,保存到m_pEnumClsObj中
  94. query+=CComBSTR(ClassName);
  95. hr=m_pWbemSvc->ExecQuery(CComBSTR("WQL"),query,WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY,
  96. 0,&m_pEnumClsObj);
  97. if (SUCCEEDED(hr))
  98. {
  99. //初始化vtProp值
  100. VariantInit(&vtProp);
  101. uReturn=0;
  102. //返回从当前位置起的第一个对象到m_pWbemClsObj中
  103. hr=m_pEnumClsObj->Next(WBEM_INFINITE,1,&m_pWbemClsObj,&uReturn);
  104. if(SUCCEEDED(hr)&&uReturn>0)
  105. {
  106. //从m_pWbemClsObj中找出ClassMember标识的成员属性值,并保存到vtProp变量中
  107. hr=m_pWbemClsObj->Get(CComBSTR(ClassMember),0,&vtProp,0,0);
  108. if (SUCCEEDED(hr))
  109. {
  110. VariantToString(&vtProp,chRetValue);
  111. VariantClear(&vtProp);//清空vtProp
  112. bRet = TRUE;
  113. }
  114. }
  115. }
  116. }
  117. if(NULL != m_pEnumClsObj)
  118. {
  119. hr=m_pEnumClsObj->Release();
  120. m_pEnumClsObj = NULL;
  121. }
  122. if(NULL != m_pWbemClsObj)
  123. {
  124. hr=m_pWbemClsObj->Release();
  125. m_pWbemClsObj = NULL;
  126. }
  127. return bRet;
  128. }
  129. BOOL CWmiInfo::GetGroupItemInfo(CString ClassName,CString ClassMember[],int n,CString &chRetValue)
  130. {
  131. USES_CONVERSION;
  132. CComBSTR query("SELECT * FROM ");
  133. CString result,info;
  134. VARIANT vtProp;
  135. ULONG uReturn;
  136. HRESULT hr;
  137. int i;
  138. BOOL bRet = FALSE;
  139. if (NULL  != m_pWbemSvc)
  140. {
  141. query+=CComBSTR(ClassName);
  142. hr=m_pWbemSvc->ExecQuery(CComBSTR("WQL"),query,WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY,0,&m_pEnumClsObj);
  143. if (SUCCEEDED(hr))
  144. {
  145. VariantInit(&vtProp); //初始化vtProp变量
  146. if(m_pEnumClsObj)
  147. {
  148. Sleep(10);
  149. uReturn=0;
  150. hr=m_pEnumClsObj->Next(WBEM_INFINITE,1,&m_pWbemClsObj,&uReturn);
  151. if (SUCCEEDED(hr) &&uReturn>0)
  152. {
  153. for(i=0;i<n;++i)
  154. {
  155. hr=m_pWbemClsObj->Get(CComBSTR(ClassMember[i]),0,&vtProp,0,0);
  156. if (SUCCEEDED(hr))
  157. {
  158. VariantToString(&vtProp,info);
  159. chRetValue+=info+_T("\t");
  160. VariantClear(&vtProp);
  161. bRet = TRUE;
  162. }
  163. }
  164. chRetValue+=_T("\r\n");
  165. }
  166. }
  167. }
  168. }
  169. if(NULL != m_pEnumClsObj)
  170. {
  171. hr=m_pEnumClsObj->Release();
  172. m_pEnumClsObj=NULL;
  173. }
  174. if(NULL != m_pWbemClsObj)
  175. {
  176. hr=m_pWbemClsObj->Release();
  177. m_pWbemClsObj=NULL;
  178. }
  179. return bRet;
  180. }
  181. void CWmiInfo::VariantToString(const LPVARIANT pVar,CString &chRetValue) const
  182. {
  183. USES_CONVERSION;
  184. CComBSTR HUGEP* pBstr;
  185. BYTE HUGEP* pBuf;
  186. LONG low,high,i;
  187. HRESULT hr;
  188. switch(pVar->vt)
  189. {
  190. case VT_BSTR:
  191. {
  192. chRetValue=W2T(pVar->bstrVal);
  193. }
  194. break;
  195. case VT_BOOL:
  196. {
  197. if(VARIANT_TRUE==pVar->boolVal)
  198. chRetValue="是";
  199. else
  200. chRetValue="否";
  201. }
  202. break;
  203. case VT_I4:
  204. {
  205. chRetValue.Format(_T("%d"),pVar->lVal);
  206. }
  207. break;
  208. case VT_UI1:
  209. {
  210. chRetValue.Format(_T("%d"),pVar->bVal);
  211. }
  212. break;
  213. case VT_UI4:
  214. {
  215. chRetValue.Format(_T("%d"),pVar->ulVal);
  216. }
  217. break;
  218. case VT_BSTR|VT_ARRAY:
  219. {
  220. hr=SafeArrayAccessData(pVar->parray,(void HUGEP**)&pBstr);
  221. hr=SafeArrayUnaccessData(pVar->parray);
  222. chRetValue=W2T(pBstr->m_str);
  223. }
  224. break;
  225. case VT_I4|VT_ARRAY:
  226. {
  227. SafeArrayGetLBound(pVar->parray,1,&low);
  228. SafeArrayGetUBound(pVar->parray,1,&high);
  229. hr=SafeArrayAccessData(pVar->parray,(void HUGEP**)&pBuf);
  230. hr=SafeArrayUnaccessData(pVar->parray);
  231. CString strTmp;
  232. high=min(high,MAX_PATH*2-1);
  233. for(i=low;i<=high;++i)
  234. {
  235. strTmp.Format(_T("%02X"),pBuf[i]);
  236. chRetValue+=strTmp;
  237. }
  238. }
  239. break;
  240. default:
  241. break;
  242. }
  243. }

上面就是一个WMI的封装,返回参数均以CString类型返回调用顺序:

1.实例化一个CWmiInfo类对象

2.调用InitWmi()函数初始化COM组件等。。。函数中有说明必须调用InitWmi初始化WMI组件,否则所有调用都无意义。

3.调用GetXXX方法获取你要获取的字段值。

4.最后使用完CWmiInfo类对象之后一定要记得调用ReleaseWmi()函数来释放资源

调用说明:

[cpp]  view plain copy
  1. /*GetSingleItemInfo()
  2. 第一个参数为要查询的类名如"Win32_Processor"表示CPU类,
  3. 第二个参数表示要查的类的成员,如"Caption"表示查询CPU的名称
  4. 第三个参数表示返回值.故可以这样调用
  5. CString strRetValue;
  6. GetSingleItemInfo(_T("Win32_Processor"),_T("Caption"),strRetValue);
  7. 一样调用成功后即可从strRetValue参数中读取出CPU的名称*/
[cpp]  view plain copy
  1. /*GetGroupItemInfo 函数与GetSingleItemInfo类似,不同的是GetSingleItemInfo一次只能查一个类成员而GetGroupItemInfo一次可以查询一个类的多个成员.GetGroupItemInfo的第三个参数表示要查询的类成员的个数,即:第二个参数CString数组的大小可以这样调用:CString strRetValue;CString [] strClassMem = {_T("Caption"),_T("CurrentClockSpeed"),_T("DeviceID"),_T("Manufacturer"),_T("Manufacturer")};GetGroupItemInfo(_T("Win32_Processor"),strClassMem,5,strRetValue);*/

可以看出WMI的调用是相当的简单只需传入你想要查询的字段所在的类名和类对象名即可~~~也许到这里有淫还会问、、、、我他妈怎么知道类名叫神马咧????类中有哪些对象咧?????

M。。。S。。。。D。。。N  可以帮到你!!!

这里教大家一个技巧,WMI的字段类名好像都是以Win32_开头。。。。如:Win32_Processor,Win32_PhysicalMemory等等。。。所以,你只要在MSDN输入Win32_就会看到很多以WMI结尾的类了。。。剩下的就是你的English水平问题了,这里google也可以帮你,如果你需要的话。

下面给大家列出一些常用的类名:

[cpp]  view plain copy
  1. // 硬件信息类名
  2. Win32_Processor, // CPU 处理器
  3. Win32_PhysicalMemory, // 物理内存条
  4. Win32_Keyboard, // 键盘
  5. Win32_PointingDevice, // 点输入设备,包括鼠标。
  6. Win32_FloppyDrive, // 软盘驱动器
  7. Win32_DiskDrive, // 硬盘驱动器
  8. Win32_CDROMDrive, // 光盘驱动器
  9. Win32_BaseBoard, // 主板
  10. Win32_BIOS, // BIOS 芯片
  11. Win32_ParallelPort, // 并口
  12. Win32_SerialPort, // 串口
  13. Win32_SerialPortConfiguration, // 串口配置
  14. Win32_SoundDevice, // 多媒体设置,一般指声卡。
  15. Win32_SystemSlot, // 主板插槽 (ISA & PCI & AGP)
  16. Win32_USBController, // USB 控制器
  17. Win32_NetworkAdapter, // 网络适配器
  18. Win32_NetworkAdapterConfiguration, // 网络适配器设置
  19. Win32_Printer, // 打印机
  20. Win32_PrinterConfiguration, // 打印机设置
  21. Win32_PrintJob, // 打印机任务
  22. Win32_TCPIPPrinterPort, // 打印机端口
  23. Win32_POTSModem, // MODEM
  24. Win32_POTSModemToSerialPort, // MODEM 端口
  25. Win32_DesktopMonitor, // 显示器
  26. Win32_DisplayConfiguration, // 显卡
  27. Win32_DisplayControllerConfiguration, // 显卡设置
  28. Win32_VideoController, // 显卡细节。
  29. Win32_VideoSettings, // 显卡支持的显示模式。
  30. // 操作系统
  31. Win32_TimeZone, // 时区
  32. Win32_SystemDriver, // 驱动程序
  33. Win32_DiskPartition, // 磁盘分区
  34. Win32_LogicalDisk, // 逻辑磁盘
  35. Win32_LogicalDiskToPartition, // 逻辑磁盘所在分区及始末位置。
  36. Win32_LogicalMemoryConfiguration, // 逻辑内存配置
  37. Win32_PageFile, // 系统页文件信息
  38. Win32_PageFileSetting, // 页文件设置
  39. Win32_BootConfiguration, // 系统启动配置
  40. Win32_ComputerSystem, // 计算机信息简要
  41. Win32_OperatingSystem, // 操作系统信息
  42. Win32_StartupCommand, // 系统自动启动程序
  43. Win32_Service, // 系统安装的服务
  44. Win32_Group, // 系统管理组
  45. Win32_GroupUser, // 系统组帐号
  46. Win32_UserAccount, // 用户帐号
  47. Win32_Process, // 系统进程
  48. Win32_Thread, // 系统线程
  49. Win32_Share, // 共享
  50. Win32_NetworkClient, // 已安装的网络客户端
  51. Win32_NetworkProtocol, // 已安装的网络协议

在、msdn中输入相应的类名即可查看个类中包括的类成员及其含义~~

正如前面所说,WMI使用相当方便,但是速度太慢,API比较复杂,但是速度很给力~~~~~可以根据自己的需求来选用实现方式~~~~

以上代码均已在vs2008中编译通过~~~~可以直接使用~~~~~~有不当的地方请指教!!

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

  1. linux 函数手册 在线,Linux系统API函数手册

    Linux系统API函数手册 (34页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 11.90 积分 (一)文件操作篇 1.creat(建立文件)头文件1 ...

  2. deepin(深度linux)dde-dock系统监控小插件(网速CPU内存)

    转载自deepin(深度linux)dde-dock系统监控小插件(网速CPU内存),仅用作个人学习备份,Mark一下 花了一周时间,研究了dde-dock官方插件开发文档和sonichy大神的项目, ...

  3. C/C++通过WMI和系统API函数获取获取系统硬件配置信息(转)

    前段时间由于项目需要,要求做一个服务器的实时性能监控(CPU.内存.网络利用率等)和读取服务器的硬件配置参数的接口供项目组使用,就是一个类似于鲁大师之类的东东吧... 当然第一想法肯定是利用Windo ...

  4. [笔记]使用API函数 GetACP 获取Windows系统当前代码页

    代码页是字符集编码的别名,也称"内码表",是特定语言的字符集的一张表. 代码页分为两种:一种是ANSI代码页:另一种是OEM代码页. ⑴OEM代码页主要是用于Windows系统中的 ...

  5. 使用API函数 GetACP 获取Windows系统当前代码页(字符编码)

    代码页是字符集编码的别名,也称"内码表",是特定语言的字符集的一张表. 代码页分为两种:一种是ANSI代码页:另一种是OEM代码页. ⑴OEM代码页主要是用于Windows系统中的 ...

  6. windows编程常用系统API函数

    windows编程常用API的函数 1. API之网络函数 2. API之消息函数 3. API之文件处理函数 4. API之打印函数 5. API之文本和字体函数 6. API之菜单函数 7. AP ...

  7. Windows 系统API 函数快速查找

    1. API之网络函数 WNetAddConnection 创建同一个网络资源的永久性连接 WNetAddConnection2 创建同一个网络资源的连接 WNetAddConnection3 创建同 ...

  8. Win32汇编:常用系统API函数

    熟练掌握Win32 API函数的参数传递,是软件逆向的基础,本章节内容将使用MASM汇编器,逐个编译这些源程序,你可以通过使用一些调试工具,这里推荐OllyDBG来附加编译后的可执行文件,进行逐个分析 ...

  9. ucos ii 46个系统API函数解析 .

    2012-08-01 11:41 106人阅读 评论(0) 收藏 编辑 删除 Void OSInit(void); 所属文件 OS_CORE.C    调用者启动代码   开关量无 OSinit()初 ...

最新文章

  1. Form_通过FND_FNDFLUPL标准功能上传CSV控件(案例)
  2. python的代码编译、代码打包方法
  3. Specification使用notin
  4. 现代教育技术课后作业(五)
  5. Android RxJava 2.0中backpressure(背压)概念的理解
  6. hadoop28---netty传对象
  7. iframe和父窗体之间的互相监听方法
  8. 虚拟机CentOS7设置远程连接
  9. Markdown简单语法总结
  10. 微课|中学生可以这样学Python(例11.2):tkinter猜数游戏(3)
  11. Selenium自动化测试-JavaScript定位
  12. 自动驾驶高精地图-概述与分析
  13. Ubuntu 搜狗输入法崩溃
  14. bat 执行php文件
  15. arcgis绘制shp文件
  16. linux hid 输入设备 在window上需要额外驱动?,什么是HID兼容设备?Win10缺少HID兼容的触摸屏驱动咋办?...
  17. CDN技术详解及实现原理
  18. Unity C# ITextSharp5.5.13 笔记
  19. C# 利用Excel及Spire.xls实现用户自定义打印模板
  20. 新手入门必懂:关于西瓜视频广告,你不可不知的基础知识

热门文章

  1. 根据秒数写一个倒计时,还有几时几分几秒开始
  2. 浙江理工大学c语言作业网站,浙江理工大学c语言期末考试模拟试卷6
  3. Vue项目中使用Highcharts
  4. tpm2-tools相关实验
  5. 系统集成部和行业应用部的职责
  6. 计算机技能大赛广播稿,运动会比赛广播稿50篇
  7. VS调试Opencv程序出现无法打开“opencv2/opencv.hpp“解决办法
  8. TensorFlow - 特征值与特征向量(Eigenvalues and eigenvectors)
  9. 你知道什么是纳米团簇吗
  10. 解除网吧 限制,网吧上网的绝招