VC++获取系统信息/获取OS/获取MAC/获取本地IP/判断是否为网吧

版权声明:本文为博主原创文章,转载请注明原帖地址。 https://blog.csdn.net/sunflover454/article/details/51525686
现在很多软件都有统计系统了,说好听点叫做统计用户习惯,改良产品,不好听点,呵呵,我就不说了。
核心我已经封装成类了,可以获取操作系统版本,MAC地址,本地IP地址,以及判定是否为网吧。

核心代码如下:

//PCInfo.h

#pragma once
#include <string>

class CPCInfo
{
public:
	CPCInfo(void);
	~CPCInfo(void);
private:
	// 获取MAC地址
	std::string& GetMAC();
	// 获取IP地址
	std::string& GetIP();
	// 获取操作系统
	std::string& GetOS();
	// 是否为网吧
	bool IsInternetBar();
public:
	std::string m_strIP;
	std::string m_strMAC;
	std::string m_strOS;
	bool m_bIsInternetBar;
};

//PCInfo.cpp

#include "PCInfo.h"
#include <winsock2.h>
#include <Iphlpapi.h>
#pragma  comment(lib,"Iphlpapi.lib")
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")


using std::string;

void byte2Hex(unsigned char bData,unsigned char hex[])
{
	int high=bData/16,low =bData %16;
	hex[0] = (high <10)?('0'+high):('A'+high-10);
	hex[1] = (low <10)?('0'+low):('A'+low-10);
}

bool getLocalMac1(unsigned char *mac) //获取本机MAC址 
{
	ULONG ulSize=0;
	PIP_ADAPTER_INFO pInfo=NULL;
	int temp = GetAdaptersInfo(pInfo,&ulSize);//第一处调用,获取缓冲区大小
	pInfo=(PIP_ADAPTER_INFO)malloc(ulSize);
	temp = GetAdaptersInfo(pInfo,&ulSize);
	int iCount=0;
	while(pInfo)//遍历每一张网卡
	{
		//  pInfo->Address MAC址
		for(int i=0;i<(int)pInfo->AddressLength;i++)
		{
			byte2Hex(pInfo->Address[i],&mac[iCount]);
			iCount+=2;
			if(i<(int)pInfo->AddressLength-1)
			{
				mac[iCount++] = ':';
			}
			else
			{
				mac[iCount++] = '#';
			}
		}
		break;
		pInfo = pInfo->Next;
	}
	free(pInfo);

	if(iCount >0)
	{
		mac[--iCount]='\0';
		return true;
	}
	else
	{
		return false;
	}
}


//通过GetAdaptersInfo函数(适用于Windows 2000及以上版本)
bool getLocalMac2(unsigned char *mac)
{
	bool ret = false;
	ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
	PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO));
	if(pAdapterInfo == NULL)
		return false;
	// Make an initial call to GetAdaptersInfo to get the necessary size into the ulOutBufLen variable
	if(GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) 
	{
		free(pAdapterInfo);
		pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);
		if (pAdapterInfo == NULL) 
			return false;
	}
	if(GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == NO_ERROR)
	{
		for(PIP_ADAPTER_INFO pAdapter = pAdapterInfo; pAdapter != NULL; pAdapter = pAdapter->Next)
		{
			// 确保是以太网
			if(pAdapter->Type != MIB_IF_TYPE_ETHERNET)
				continue;
			// 确保MAC地址的长度为 00-00-00-00-00-00
			if(pAdapter->AddressLength != 6)
				continue;
			char acMAC[20] = {0};
			sprintf(acMAC, "%02X:%02X:%02X:%02X:%02X:%02X",
				int (pAdapter->Address[0]),
				int (pAdapter->Address[1]),
				int (pAdapter->Address[2]),
				int (pAdapter->Address[3]),
				int (pAdapter->Address[4]),
				int (pAdapter->Address[5]));
			memcpy(mac,acMAC,20);
			ret = true;
			break;
		}
	}
	free(pAdapterInfo);
	return ret;
}


//通过GetAdaptersAddresses函数(适用于Windows XP及以上版本)
bool getLocalMac3(unsigned char *mac)
{
	bool ret = false;
	ULONG outBufLen = sizeof(IP_ADAPTER_ADDRESSES);
	PIP_ADAPTER_ADDRESSES pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
	if (pAddresses == NULL) 
		return false;
	// Make an initial call to GetAdaptersAddresses to get the necessary size into the ulOutBufLen variable
	if(GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW)
	{
		free(pAddresses);
		pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
		if (pAddresses == NULL) 
			return false;
	}

	if(GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAddresses, &outBufLen) == NO_ERROR)
	{
		// If successful, output some information from the data we received
		for(PIP_ADAPTER_ADDRESSES pCurrAddresses = pAddresses; pCurrAddresses != NULL; pCurrAddresses = pCurrAddresses->Next)
		{
			// 确保MAC地址的长度为 00-00-00-00-00-00
			if(pCurrAddresses->PhysicalAddressLength != 6)
				continue;
			char acMAC[20] = {0};
			sprintf(acMAC, "%02X:%02X:%02X:%02X:%02X:%02X",
				int (pCurrAddresses->PhysicalAddress[0]),
				int (pCurrAddresses->PhysicalAddress[1]),
				int (pCurrAddresses->PhysicalAddress[2]),
				int (pCurrAddresses->PhysicalAddress[3]),
				int (pCurrAddresses->PhysicalAddress[4]),
				int (pCurrAddresses->PhysicalAddress[5]));
			memcpy(mac,acMAC,20);
			ret = true;
			break;
		}
	} 
	free(pAddresses);
	return ret;
}



bool GetLocalIP(char* ip)
{
	//1.初始化wsa
	WSADATA wsaData;
	int ret=WSAStartup(MAKEWORD(2,2),&wsaData);
	if (ret!=0)
	{
		return false;
	}
	//2.获取主机名
	char hostname[256];
	ret=gethostname(hostname,sizeof(hostname));
	if (ret==SOCKET_ERROR)
	{
		return false;
	}
	//3.获取主机ip
	HOSTENT* host=gethostbyname(hostname);
	if (host==NULL)
	{
		return false;
	}
	//4.转化为char*并拷贝返回
	strcpy(ip,inet_ntoa(*(in_addr*)*host->h_addr_list));
	return true;
}


CPCInfo::CPCInfo(void)
:m_bIsInternetBar(false)
{
	m_strIP = GetIP();
	m_strMAC = GetMAC();
	m_strOS = GetOS();
	m_bIsInternetBar = IsInternetBar();
}

//读取操作系统的名称
string GetSystemName()
{
	SYSTEM_INFO info;        //用SYSTEM_INFO结构判断64位AMD处理器 
	GetSystemInfo(&info);    //调用GetSystemInfo函数填充结构 
	OSVERSIONINFOEX os; 
	os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);   

	string osname = "unknown OperatingSystem.";

	if(GetVersionEx((OSVERSIONINFO *)&os))
	{ 
		//下面根据版本信息判断操作系统名称 
		switch(os.dwMajorVersion)//判断主版本号
		{
		case 4:
			switch(os.dwMinorVersion)//判断次版本号 
			{ 
			case 0:
				if(os.dwPlatformId==VER_PLATFORM_WIN32_NT)
					osname = "Microsoft Windows NT 4.0"; //1996年7月发布 
				else if(os.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
					osname = "Microsoft Windows 95";
				break;
			case 10:
				osname = "Microsoft Windows 98";
				break;
			case 90:
				osname = "Microsoft Windows Me";
				break;
			}
			break;

		case 5:
			switch(os.dwMinorVersion)	//再比较dwMinorVersion的值
			{ 
			case 0:
				osname = "Microsoft Windows 2000";//1999年12月发布
				break;

			case 1:
				osname = "Microsoft Windows XP";//2001年8月发布
				break;

			case 2:
				if(os.wProductType==VER_NT_WORKSTATION 
					&& info.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
				{
					osname = "Microsoft Windows XP Professional x64 Edition";
				}
				else if(GetSystemMetrics(SM_SERVERR2)==0)
					osname = "Microsoft Windows Server 2003";//2003年3月发布 
				else if(GetSystemMetrics(SM_SERVERR2)!=0)
					osname = "Microsoft Windows Server 2003 R2";
				break;
			}
			break;

		case 6:
			switch(os.dwMinorVersion)
			{
			case 0:
				if(os.wProductType == VER_NT_WORKSTATION)
					osname = "Microsoft Windows Vista";
				else
					osname = "Microsoft Windows Server 2008";//服务器版本 
				break;
			case 1:
				if(os.wProductType == VER_NT_WORKSTATION)
					osname = "Microsoft Windows 7";
				else
					osname = "Microsoft Windows Server 2008 R2";
				break;
			case 2:
				if(os.wProductType == VER_NT_WORKSTATION)
					osname = "Microsoft Windows 8";
				else
					osname = "Microsoft Windows Server 2012";
				break;
			case 3:
				if(os.wProductType == VER_NT_WORKSTATION)
					osname = "Microsoft Windows 8.1";
				else
					osname = "Microsoft Windows Server 2012 R2";
				break;
			}
			break;

		case 10:
			switch(os.dwMinorVersion)
			{
			case 0:
				if(os.wProductType == VER_NT_WORKSTATION)
					osname = "Microsoft Windows 10";
				else
					osname = "Microsoft Windows Server 2016 Technical Preview";//服务器版本 
				break;
			}
			break;
		}
	}//if(GetVersionEx((OSVERSIONINFO *)&os))
	//https://msdn.microsoft.com/en-us/library/ms724832.aspx
	return osname;
} 


CPCInfo::~CPCInfo(void)
{
}


// 获取MAC地址
string& CPCInfo::GetMAC()
{
	unsigned char szMac[20] = {0};
	//为了确保获取到MAC地址,通过三种方式来获取
	if(!getLocalMac3(szMac))
	{
		if(!getLocalMac2(szMac))
		{
			getLocalMac1(szMac);
		}
	}
	m_strMAC.empty();
	m_strMAC.append((const char*)szMac,sizeof(szMac));

	return m_strMAC;
}

// 获取IP地址
string& CPCInfo::GetIP()
{
	char ip[30] = {'\0'};
	if (GetLocalIP(ip))
	{
		m_strIP.empty();
		m_strIP.append(ip,sizeof(ip));
	}

	return m_strIP;
}

// 获取操作系统
string& CPCInfo::GetOS()
{
	m_strOS = GetSystemName();

	return m_strOS;
}

bool IsHaveKey(HKEY hKey, char* lpSubKey)
{
	HKEY phkResult = 0;	
	if (ERROR_SUCCESS == RegOpenKeyExA(hKey, lpSubKey, 0, KEY_QUERY_VALUE, &phkResult))
	{
		RegCloseKey(phkResult);
		return true;
	}
	return false;
}

// 是否为网吧
bool CPCInfo::IsInternetBar()
{
	char* NetRoomKey[] =
	{
		"SOFTWARE\\Hintsoft\\PubwinClient",
		"SOFTWARE\\Hintsoft\\pubwin",
		"SOFTWARE\\Sicent\\wx2004Clt",
		"SOFTWARE\\MpSoft\\smenu",
		"SOFTWARE\\Microsoft\\jingzu",
		"SOFTWARE\\iCafe8",
		"SOFTWARE\\Goyoo\\i8desk",
		"SOFTWARE\\Hintsoft1\\XunShanPro",
		"SOFTWARE\\SyncExpertNetBar",
		"SOFTWARE\\EYOOCLIENTSTATUS",
		"SOFTWARE\\Richtech",
		"SOFTWARE\\\u676d\u5dde\u987a\u7f51\u4fe1\u606f\u6280\u672f\u6709\u9650\u516c\u53f8\\\u7f51\u7ef4\u5927\u5e08\u874c\u86aa\u5a31\u4e50\u5e73\u53f0",
		"SOFTWARE\\iCafe8",
		"SOFTWARE\\Sicent\\wx2004Clt",
		"SOFTWARE\\Sicent\\WxAdv",
		"SOFTWARE\\Grabsun\\Netsense",
	};

	for (int i = 0; i < sizeof(NetRoomKey) / sizeof(char*); i++)
	{
		if (IsHaveKey(HKEY_LOCAL_MACHINE, NetRoomKey[i]))
		{
			m_bIsInternetBar = true;
			break;
		}
	}

	return m_bIsInternetBar;
}

有个使用注意事项,不注意会导致Win8以上系统获取到的操作系统信息错误
具体注意事项在这篇文章中有详细说明:http://blog.csdn.net/sunflover454/article/details/51525179
执行结果如下:



测试工程为VS2010 MFC项目,下载链接:http://download.csdn.net/detail/sunflover454/9534014


猜你喜欢

转载自blog.csdn.net/sunflover454/article/details/51525686