使用CMD命令和管道获取MAC地址

该方法有BUG,如果网卡信息中包含有字符“#”(常见于一些安装了虚拟机的机器中),管道读取CMD输出内容时可能会假死,不会返回。建议使用GetAdaptersAddresses函数来获取MAC地址。具体请参照《使用GetAdaptersAddresses函数获取物理MAC地址

1、头文件

// Temporary.h
//
#ifndef _TEMPORARY_H_
#define _TEMPORARY_H_

#include <vector>

class CTemporary
{
public:
    CTemporary() {};

    BOOL GetMacAddr(OUT std::vector<CString>& vtMacAddr);

private:
    BOOL _AnalyseCmdResult(LPCSTR pszCmdRes,
        std::vector<CString>& vtMacAddr);
};

#endif // !_TEMPORARY_H_

2、源文件

// Temporary.cpp
//

#include "Temporary.h"

CTemporary::CTemporary()
{
}

BOOL CTemporary::GetMacAddr(std::vector<CString>& vtMacAddr)
{
    CString sCmd(_T("IPCONFIG /ALL"));

    BOOL bResult = FALSE;
    SECURITY_ATTRIBUTES securityAttr;
    HANDLE hReadPipe = NULL, hWritePipe = NULL;
    securityAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
    securityAttr.lpSecurityDescriptor = NULL;
    securityAttr.bInheritHandle = TRUE;
    // 创建管道
    bResult = CreatePipe(&hReadPipe, &hWritePipe, &securityAttr, 0);
    if (FALSE == bResult)
    {
        return FALSE;
    }

    PROCESS_INFORMATION processInfo;
    ZeroMemory(&processInfo, sizeof(processInfo));
    do
    {
        // 控制命令行窗口信息
        STARTUPINFO startupInfo;
        startupInfo.cb = sizeof(STARTUPINFO);
        GetStartupInfo(&startupInfo);
        startupInfo.hStdError = hWritePipe;
        startupInfo.hStdOutput = hWritePipe;
        startupInfo.wShowWindow = SW_HIDE;  // 隐藏命令行窗口
        startupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
        // 创建获取命令行进程
        bResult = CreateProcess(NULL, sCmd.GetBuffer(), NULL, NULL,
            TRUE, 0, NULL, NULL, &startupInfo, &processInfo);
        sCmd.ReleaseBuffer();
        if (FALSE == bResult)
        {
            break;
        }

        WaitForSingleObject(processInfo.hProcess, INFINITE);

        const UINT uiBuffSize = 1024 * 10;
        PSTR pszBuffer = new char[uiBuffSize];     // 放置命令行输出缓冲区
        ZeroMemory(pszBuffer, uiBuffSize);

        DWORD dwCount = 0;
        bResult = ReadFile(hReadPipe, pszBuffer, uiBuffSize, &dwCount, 0);
        if (FALSE == bResult)
        {
            break;
        }

        bResult = _AnalyseCmdResult(pszBuffer, vtMacAddr);
    } while (FALSE);

    // 关闭所有的句柄
    if (hWritePipe)
    {
        CloseHandle(hWritePipe);
    }

    if (processInfo.hProcess)
    {
        CloseHandle(processInfo.hProcess);
    }

    if (processInfo.hThread)
    {
        CloseHandle(processInfo.hThread);
    }

    if (hReadPipe)
    {
        CloseHandle(hReadPipe);
    }

    return bResult;
}

BOOL CTemporary::_AnalyseCmdResult(LPCSTR pszCmdRes,
    std::vector<CString>& vtMacAddr)
{
    const char szSearchTarget[2][128] = {
        "物理地址. . . . . . . . . . . . . : ",
        "Physical Address. . . . . . . . . : "
    };

    char szMacAddr[24];
    LPCSTR pEndIndex = NULL;
    LPCSTR pStartIndex = NULL;
    const char szIgnoreMac[] = "00-00-00";
    for (UINT i = 0; i < 2; i++)
    {
        pStartIndex = pszCmdRes;
        do
        {
            pStartIndex = strstr(pStartIndex, szSearchTarget[i]);
            if (NULL == pStartIndex)
            {
                break;
            }

            pStartIndex += strlen(szSearchTarget[i]);
            pEndIndex = strchr(pStartIndex, '\r');
            if (NULL == pEndIndex)
            {
                pEndIndex = strchr(pStartIndex, '\n');
                if (NULL == pEndIndex)
                {
                    ATLASSERT(NULL != pEndIndex);
                    continue;
                }
            }

            strncpy_s(szMacAddr, 24, pStartIndex, pEndIndex - pStartIndex);
            pStartIndex = pEndIndex;
            if (szMacAddr == strstr(szMacAddr, szIgnoreMac))
            {
                continue;
            }

            vtMacAddr.push_back(CString(ATL::CA2T(szMacAddr)));
        } while (TRUE);
    }

    return vtMacAddr.size() ? TRUE : FALSE;
}

3、测试与样例

#include "Temporary.h"
#include <iostream>

void main()
{
    std::vector<CString> vtMacAddr;
    CTemporary temporary;
    if (FALSE == temporary.GetMacAddr(vtMacAddr))
    {
        std::cout << _T("Get mac address failed.") << std::endl;
        return;
    }

    for (UINT uiIndex = 0; uiIndex < vtMacAddr.size(); uiIndex++)
    {
        std::cout << vtMacAddr[uiIndex] << std::endl;
    }

    system("pause");
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值