(转)通过WMI获取网卡MAC地址、硬盘序列号、主板序列号、CPU ID、BIOS序列号
最近由于项目的需要,需要在程序中获取机器的硬盘序列号和MAC地址等信息,在C#下,可以很容易的获得这些信息,但是在C++程序中感觉比较麻烦。经过百度,发现很多大虾都是通过WMI来获取这些硬件信息的,网上也有相关的代码,通过实际调试,也发现确实可以通过WMI来获取这些信息。前两天,在网上突然搜到一位大牛写的比较完整的程序,为了以后使用方便,就转载记录一下。同时,也会在大牛的代码中增加一些自己的注释,都是自己在实际使用过程中遇到的问题。
#define _WIN32_DCOM
#include "stdafx.h"
#include<iostream>
#include<fstream>
#include<string>
#include "direct.h"
#include <tchar.h>
#include <time.h>
#include <comdef.h>
#include <Wbemidl.h>
#include <conio.h>
#include "atlstr.h"
#include "atlbase.h"
//#include "TcpCtl.h"
//#include "winsock2.h"
//#include "InitDll.h"
using namespace std;
# pragma comment(lib, "wbemuuid.lib")
# pragma comment(lib, "ws2_32.lib")
//通过WMI获取主板号
BOOL ManageWMIBord(char bord[])
{
HRESULT hres;
// Step 1: 初始化COM
//hres = CoInitializeEx(0, COINIT_MULTITHREADED); //网上的代码都是使用这行语句进行初始化,但是我在实际使用中,发现也可以采用下面的语句进行初始化
hres = CoInitialize(0);
//网上的代码是没有注释下面这个判断的,但是实际使用中发现,如果之前已经初始化成功了,在第二次初始化的时候,下面的代码就会导致返回false,所以,实际使用中我就注释掉了
//if (FAILED(hres))
//{
// cout << "Failed to initialize COM library. Error code = 0x"
// << hex << hres << endl;
// return false; // Program has failed.
//}
// Step 2: 设置COM的安全认证级别
//在实际使用过程中,我发现如果这一步不注释掉的话,程序总是返回false,注释掉之后程序反而可以正常运行,原因未知
// Note: If you are using Windows 2000, you need to specify -
// the default authentication credentials for a user by using
// a SOLE_AUTHENTICATION_LIST structure in the pAuthList ----
// parameter of CoInitializeSecurity ------------------------
////hres = CoInitializeSecurity(
//// NULL,
//// -1, // COM authentication
//// NULL, // Authentication services
//// NULL, // Reserved
//// RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication
//// RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
//// NULL, // Authentication info
//// EOAC_NONE, // Additional capabilities
//// NULL // Reserved
//// );
////
////if (FAILED(hres))
////{
//// cout << "Failed to initialize security. Error code = 0x"
//// << hex << hres << endl;
//// CoUninitialize();
//// return false; // Program has failed.
////}
// Step 3: 获得WMI连接COM接口
IWbemLocator *pLoc = NULL;
hres = CoCreateInstance(
CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID *) &pLoc);
if (FAILED(hres))
{
cout << "Failed to create IWbemLocator object."
<< " Err code = 0x"
<< hex << hres << endl;
CoUninitialize();
return false; // Program has failed.
}
// Step 4: 通过连接接口连接WMI的内核对象名"ROOT//CIMV2"
IWbemServices *pSvc = NULL;
hres = pLoc->ConnectServer(
_bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
NULL, // User name. NULL = current user
NULL, // User password. NULL = current
0, // Locale. NULL indicates current
NULL, // Security flags.
0, // Authority (e.g. Kerberos)
0, // Context object
&pSvc // pointer to IWbemServices proxy
);
if (FAILED(hres))
{
cout << "Could not connect. Error code = 0x"
<< hex << hres << endl;
pLoc->Release();
CoUninitialize();
return false; // Program has failed.
}
//cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl;
// Step 5: 设置请求代理的安全级别
hres = CoSetProxyBlanket(
pSvc, // Indicates the proxy to set
RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
NULL, // Server principal name
RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
NULL, // client identity
EOAC_NONE // proxy capabilities
);
if (FAILED(hres))
{
cout << "Could not set proxy blanket. Error code = 0x"
<< hex << hres << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
return false; // Program has failed.
}
// Step 6: 通过请求代理来向WMI发送请求----
// For example, get the name of the operating system
IEnumWbemClassObject* pEnumerator = NULL;
hres = pSvc->ExecQuery(
bstr_t("WQL"),
//bstr_t("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = 'TRUE'"),
bstr_t("SELECT * FROM Win32_BaseBoard"),//只需要通过修改这里的查询语句,就可以实现对MAC地址等其他信息的查询
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator);
if (FAILED(hres))
{
cout << "Query for Network Adapter Configuration failed."
<< " Error code = 0x"
<< hex << hres << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
return false; // Program has failed.
}
// Step 7: 循环枚举所有的结果对象
IWbemClassObject *pclsObj;
ULONG uReturn = 0;
while (pEnumerator)
{
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
&pclsObj, &uReturn);
if(0 == uReturn)
{
break;
}
VARIANT vtProp;
VariantInit(&vtProp);
hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0);//查询不同的硬件信息,除了修改上面的查询语句,这里的字段也要修改
if(!FAILED(hr))
{
CW2A tmpstr1(vtProp.bstrVal);
strcpy_s(bord,200,tmpstr1);//这里的200是可调的,自己根据实际情况设置,但是肯定不能大于bord的长度
//cout << "BordSN:" << sn << endl;
}
VariantClear(&vtProp);
}//end while
// 释放资源
pSvc->Release();
pLoc->Release();
pEnumerator->Release();
pclsObj->Release();
CoUninitialize();
return true; // Program successfully completed.
}
附:
// WQL查询语句
const T_WQL_QUERY szWQLQuery[] = {
// 网卡原生MAC地址
"SELECT * FROM Win32_NetworkAdapter WHERE (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))",
L"PNPDeviceID",
// 硬盘序列号
"SELECT * FROM Win32_DiskDrive WHERE (SerialNumber IS NOT NULL) AND (MediaType LIKE 'Fixed hard disk%')",
L"SerialNumber",
// 主板序列号
"SELECT * FROM Win32_BaseBoard WHERE (SerialNumber IS NOT NULL)",
L"SerialNumber",
// 处理器ID
"SELECT * FROM Win32_Processor WHERE (ProcessorId IS NOT NULL)",
L"ProcessorId",
// BIOS序列号
"SELECT * FROM Win32_BIOS WHERE (SerialNumber IS NOT NULL)",
L"SerialNumber",
// 主板型号
"SELECT * FROM Win32_BaseBoard WHERE (Product IS NOT NULL)",
L"Product",
// 网卡当前MAC地址
"SELECT * FROM Win32_NetworkAdapter WHERE (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))",
L"MACAddress",
//当前机器的型号和厂商
"SELECT * FROM Win32_computersystem",
L"Manufacturer",L"Model"
}
(转)通过WMI获取网卡MAC地址、硬盘序列号、主板序列号、CPU ID、BIOS序列号的更多相关文章
- 转: 通过WMI获取网卡MAC地址、硬盘序列号、主板序列号、CPU ID、BIOS序列号
最近由于项目的需要,需要在程序中获取机器的硬盘序列号和MAC地址等信息,在C#下,可以很容易的获得这些信息,但是在C++程序中感觉比较麻烦.经过百度,发现很多大虾都是通过WMI来获取这些硬件信息的,网 ...
- 通过WMI获取网卡MAC地址、硬盘序列号、主板序列号、CPU ID、BIOS序列号
转载:https://www.cnblogs.com/tlduck/p/5132738.html #define _WIN32_DCOM #include<iostream> #inclu ...
- 获取网卡MAC、硬盘序列号、CPU_ID、BIOS编号
抄来的 获取网卡MAC.硬盘序列号.CPU ID.BIOS编号 本文中所有原理及思想均取自网络,有修改.其中获取硬盘序列号.获取CPU编号.获取BIOS编号的原始代码的著作权归各自作者所有. 以下代码 ...
- Python 获取 网卡 MAC 地址
/*********************************************************************** * Python 获取 网卡 MAC 地址 * 说明: ...
- windows平台下获取网卡MAC地址、硬盘序列号、主板序列号、CPU ID、BIOS序列号
转自http://blog.csdn.net/jhqin/article/details/5548656,如有侵权,请联系本人删除,谢谢!! 头文件:WMI_DeviceQuery.h /* ---- ...
- VC++获取网卡MAC、硬盘序列号、CPU ID、BIOS编号
以下代码可以取得系统特征码(网卡MAC.硬盘序列号.CPU ID.BIOS编号) BYTE szSystemInfo[4096]; // 在程序执行完毕后,此处存储取得的系统特征码 UINT uSys ...
- 使用WinPcap获取网卡MAC地址
关键字:WinPcap 网卡 MAC地址 作者:txw1958 在WpdPack_4_1_2\WpdPack\Examples-remote\PacketDriver\GetMacAddress\目录 ...
- php获取网卡MAC地址源码
<?php /** 获取网卡的MAC地址原码:目前支持WIN/LINUX系统 获取机器网卡的物理(MAC)地址 **/ class GetMacAddr{ var $return_array = ...
- matlab 获取网卡MAC地址
输入命令 [sta,MACres] = dos('getmac'); 其中MACres 存储的信息即为网卡的 相关信息. 如果想判断读取的网卡信息是否有指定信息可以如下输入 USER1 = strf ...
随机推荐
- [POI2007]驾驶考试egz
题目 BZOJ 神仙题,可比那些氵紫题有意思多了 做法 \(i\)能作为起始点,当\(i\)能到达\(1\)~\(i-1\)和\(i+1\)~\(n\) 这样处理显然会麻烦,因为要从每个点都特判一次 ...
- 20145240 《Java程序设计》第十周学习总结
20145240 <Java程序设计>第十周学习总结 教材学习内容总结 网络编程 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据. 程序员所作的事情就是把数据发送到指定的位置 ...
- Hadoop相关知识整理系列之一:HBase基本架构及原理
1. HBase框架简单介绍 HBase是一个分布式的.面向列的开源数据库,它不同于一般的关系数据库,是一个适合于非结构化数据存储的数据库.另一个不同的是HBase基于列的而不是基于行的模式.HBas ...
- Go reflect反射
Go语言中的反射非常强大,可以对string, int, struct, func...进行反射,使用起来也比较简单. 示例1:反射函数 package main import ( "fmt ...
- mongodb count 导致不正确的数量(mongodb count 一个坑)
在mongodb 集群中,if 存在orphaned documents 和chunk migration, count查询可能会导致一个不正确的查询结果,例如我就是踩的这个坑,先不说话,看结果: ...
- 搭建TXManager分布式事务协调者
事务分组id 缓存到redis 需要配置连接到自己的 redis地址 启动后:
- poj 1061 青蛙的约会 扩展欧几里德
青蛙的约会 Time Limit: 1000MS Memory Limit: 10000K Description 两 只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们 ...
- Debugging Tools for Windows__from WDK7
1. 主要要用到两个工具: (1).WinDBG 这个主要用于 非IDE下 调试程序/查看信息等 (2).cdb.exe 这个主要是用在 Qt5.3.2 for VS10 的单步调试器 2. WDK7 ...
- Php加速原理及工具试验
Php加速原理及工具测试 本实验相关软件地址:http://pan.baidu.com/s/1dDuwvE5 第一部分.Php加速分类: 一.缓冲层级别的优化 1.xCache是把 PHP 操作码缓存 ...
- Qt5 窗口内的控件随窗口大小自动变化
http://www.bubuko.com/infodetail-827151.html 讲的很详细