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

转载自:http://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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值